有关Java反射机制整理

1:反射的作用
笼统的来说,反射可以让Java程序在运行阶段对类进行操作。
在说这个问题前我们需要了解一下Java程序运行的过程。

编译源码->编译->class文件
这个过程是我们所熟悉的,可是class文件并不只是能够直接运行的。

class->装载->获得原信息
随后class会由类加载器装载,然后在JVM中将形成一份描述class结构的原信息对象。
通过原信息对象可以获知Class文件的结构信息,如构造函数,属性方法等。

之后的过程发生在虚拟机里
加载->链接->校验->转换->解析->初始化
之后虚拟机把原信息对象加载到内存,并对数据进行校验、转换、解析和初始化、最终形成可以被虚拟机直接使用的Java类型。

而类的初始化的时机大概有下面几个:
1:使用new关键字实例化对象的时候,读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
2:当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
当虚拟机启动是,用户需要指定一个要执行的主类(包含main()方法的那个类)虚拟机会先初始化这个主类。
3:使用java.lang.reflect包方法对类进行反射调用的时候,如果类没有进行过初始化则需要先触发其初始化。

也就是说在类的初始化的过程中会执行反射调用,而这个过程在编译之后发生!

接下来是实现细节:

Java提供了一个javaBean规范来用于反射:
javaBean的规范为
1:必须提供私有字段
2:必须提供get和set方法
3:必须提供无参构造
4:必须实现序列化接口java.io.Serializable

但是使用反射往往要经历以下几个步骤:
1:获得对象
2:获得构造对象
3:获得实例

一:获得class对象
我们可以通过三种不同的方法来获得class对象:
方式:

  • 1:通过字符串(全限定类名)获得
  •  格式:Class	clazz=Class.forName(String)
    
  •  全限定类名:包名+类名
    
  • 2:通过Java类型获得
  •  格式: Class clazz=类型.class;
    
  • 3:通过实例对象(变量名)获得
  •  格式:Class clazz=obj.getClass()
    

此处假设我们已经通过三种方法之一获得了class对象;
2:获得构造对象
2.1:获得公有构造对象,并调用
使用getConstructor()获得单个构造对象(若无参则()内不填任何东西若有参则如下)

  • Constructor constroctor=clazz.getConstructor(String.class,...);
    

2.2:获得私有构造对象
1:获得指定形参的私有构造
使用getDeclaredConstructor()获得单个构造对象(无参情况同上)

  • Constructor  constructor=clazz.getDeclaredConstructor(String.class,...);
    

2:通知JVM虚拟机允许实例化的私有构造(默认是不允许的)
constructor.setAccessible(true);

默认已获得构造 constructor
3:获得实例
获得实例并传入参数。

  • Object object=constructor.newInstance("111");
    

二:获取成员变量并使用
关键字:
(1)Field[] getFields() ;获取所有的“公有字段
(2)Field[] getDeclaredFileds();获取所有字段,包括私有、默认、受保护、公有
(3)public Field getField(String fieldName);获取某个公有字段
(4)public Filed geDeclaredtField(String fieldName);;获取某个字段,包括私有、默认、受保护、公有

具体操作与获得构造方法的方式相同,不再详述。

三:获取成员方法并使用
(1)Method[] getMethods;获得所有“公有成员方法”
(2)Method[] getDeclaredMetod;获取所有的成员方法,获取所有字段,包括私有、默认、受保护、公有
(3)Method getMethod(String name,Class<?>… parameterTypes)获取某个公有成员方法
参数:
name : 方法名;
Class … : 形参的 Class 类型对象
(4)Method getDeclaredMethod(String name,Class<?>… parameterTypes);获取某个方法,包括私有、默认、受保护、公有

看到这里,相信前面关于构造函数的几个方法,大家也能猜出来了,可以测试下自己猜的是否正确。了解下java的命名规则,就可以通过命名来大致的了解该方法的功用了。

此外还可以通过set来获取字段的值,通过invoke来调用成员方法。这位博主在这方面说的非常详细就不再复述
https://blog.csdn.net/lwl20140904/article/details/80163880

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值