首页 > 编程语言 >java反射

java反射

时间:2023-03-13 10:24:09浏览次数:56  
标签:反射 java 对象 class clazz 获取 https Class

1.反射机制的概念及作用(原文链接:https://blog.csdn.net/lililuni/article/details/83449088)

      JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

      实际上,我们创建的每一个类也都是对象,即类本身是java.lang.Class类的实例对象。这个实例对象称之为类对象,也就是Class对象。那么,Class对象又是什么对象呢?

(原文链接:https://blog.csdn.net/sinat_38259539/article/details/71799078)

反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
(其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
如图是类的正常加载过程:反射的原理在与class对象。
熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

 其中这个Class对象很特殊。我们先了解一下这个Class类。

 从图中可以得出以下几点:(原文链接:https://blog.csdn.net/lililuni/article/details/83449088)

(1)Class 类的实例对象表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有很多的实例,每个类都有唯一的Class对象。
(2)Class 类没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机自动构造的。也就是说我们不需要创建,JVM已经帮我们创建了。
(3)Class 对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。

2.反射所在的包及常用的相关方法(原文链接:https://blog.csdn.net/qq_51515673/article/details/124830558)
所在包:java.lang.reflect.*;

常用的方法:

//获取包名、类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名
 
//获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)
 
//获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)
 
//获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)
 
//反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(222,"韦小宝");//执行有参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法
 
//反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null
 
//反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法

3.反射获取类对象的三种方式(原文链接:https://blog.csdn.net/qq_51515673/article/details/124830558)

① 调用某个类的对象的getClass()方法,即:对象.getClass();

Person p = new Person();
Class clazz = p.getClass();
注意:此处使用的是Object类中的getClass()方法,因为所有类都继承Object类,所以调用Object类中的getClass()方法来获取。

② 调用类的class属性类获取该类对应的Class对象,即:类名.class

Class clazz = Person.class;
③ 使用Class类中的forName()静态方法(最安全,性能最好)即:Class.forName(“类的全路径”)

Class clazz = Class.forName("类的全路径");
注意:在运行期间,一个类,只有一个Class对象产生。

三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。

package com.reflection;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Person {

    private String name;
    public int age;

    public Person()
    {}
    
    public Person(String n,int a)
    {
        name = n;
        age = a;
    }
    
    public void run()
    {
        System.out.println("跑");
    }
    
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Person p = new Person();
        //1.调用某个类的对象的getClass()方法,即:对象.getClass();
        Class class1 = p.getClass();
        Object  Field[] =  class1.getDeclaredFields();
        for(int i=0;i<Field.length;i++)
        {
            System.out.println(Field[i]);
        }
        
        //2.调用类的class属性类获取该类对应的Class对象,即:类名.class
        Class class2 = Person.class;
        Object  Constructor[] = class2.getConstructors();
        for(int i=0;i<Constructor.length;i++)
        {
            System.out.println(Constructor[i]);
        } 
        
        //3.使用Class类中的forName()静态方法(最安全,性能最好)即:Class.forName(“类的全路径”)
        Class class3 = Class.forName("com.reflection.Person");
        Method ms[] = class3.getMethods();
        for(Method t:ms)
        {
            System.out.println(t);
            System.out.println(t.getName());    
            Class<?>[] pt=t.getParameterTypes();
            System.out.println(Arrays.toString(pt));        
        }
    }
}

 



 

 

 

 



 

 

 

 

 

 

 

 

 

参考文章:

https://blog.csdn.net/qq_51515673/article/details/124830558

https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html

https://blog.csdn.net/lililuni/article/details/83449088

https://www.cnblogs.com/adamjwh/p/9683705.html

https://blog.csdn.net/sinat_38259539/article/details/71799078

标签:反射,java,对象,class,clazz,获取,https,Class
From: https://www.cnblogs.com/YorkZhangYang/p/17210424.html

相关文章

  • 【面试系列1】Java基础
    1.面向对象三大特征封装   1. 属性与方法:属性描述同一类事务的特征、方法描述同一类事务的操作。封装就是将同一类事务的属性、方法归结到同一个类里面。  2. ......
  • java初识
    一java简介二开发环境搭建三开发第一个java程序四使用Eclipse进行java程序开发  Java简介java是一门面向对象的程序设计语言1995年由sun公司发布2010......
  • java学习日记20230312-构造方法
    构造方法/构造器基本语法[修饰符]方法名(形参列表){方法体;}构造器的修饰符可以是默认;构造器没有返回值;方法名和类名字必须一样;参数列表和成员方法一样的规则;构......
  • 【转】Golang Reflect反射的使用详解1 --- makeFunc的使用
     转,原文: https://studygolang.com/articles/12300 ---------------------------------- Whatyouarewastingtodayistomorrowforthosewhodiedyesterday......
  • Java基础知识点(集合、ArrayList集合、基本数据类型对应的包装类及
    1.为什么要有集合?集合它可以自动扩容。2.集合存储数据类型的特点:不能直接存基本数据类型,需要将其变为包装类再存入,可以存引用数据类型。二:集合和数组的对比长度:数组的长度固......
  • 学习java第三周
    前言:这周过的很充实,因为对之前的内容没有很好理解本周一部分时间消化之前内容,经过三周的学习,对Java开始有了自己的认知,长路漫漫对自己的学习情况并不是很满意.对本周内......
  • java学习日记20230311-方法重载/可变参数/作用域
    方法重载java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致:System.out.println();减轻了起名的麻烦减轻了记名的麻烦方法名必须相同形参列表必须不同(个......
  • java.lang.IllegalStateException: couldn't determine local port. Please set sprin
    2023-03-12记录一下出现上述问题的原因(1)问题描述:在打包springboot项目时,出现了上述问题(2)产生原因:在打包时,项目的生命周期中没有关闭test(3)解决方法:关闭test,如图,之后......
  • 学java前预备知识
    计算机预科1.打开CMD的方式开始+系统+命令提示符。Win+R输入CMD打开控制台(推荐使用)。在任意文件夹下,按住Shift键+鼠标右键打开命令行窗口。在资源管理......
  • JavaScript异步编程的深入理解,使用回调函数实现异步编程
    异步编程是指在程序运行时,任务不会按照函数调用的顺序依次执行,而是可以同时执行多个任务。JavaScript异步编程有很多种方式,例如使用回调函数、Promise、async/await等。下面......