Object(源头)
Java的一切都是对象
Object是反射的源头
Class是反射的导演
Class(导演)
在Java程序运行时,JVM会对所有的对象维护一个独一无二的类型标识,这就是Class对象。
Java的基本类型和关键字void也对应一个Class对象。
相同元素类型和维数的数组也对应一个Class对象。
获取Class对象的几种方法:
- 一个对象通过.class
- 一个对象通过getClass方法
- Class.forName(String)
Class对象有一些重要的方法:
- getConstructor系列,用于获取构造方法
- getField系列,用于获取属性
- getMethod系列,用于获取方法
上述系列中包含Declared系列,可以获取当前对象的所有类型的反射(包含private),但是不能获取父类的反射
Constructor,Field,Method都是Class导演的三大利器,它们都位于java.lang.reflect
包下,接下来将分别对这三大利器进行展示。
Constructor
通过Class对象获取到的Constructor对象之后,最常用的操作就是用来实例化对象,调用newInstance方法即可。
其实在Class对象中也有一个newInstance方法,也可以用来实例化对象,它们的区别是什么呢?
- Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数,要求被调用的构造函数是可见的,也即必须是public类型的;
- Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数,在特定的情况下,可以调用私有的构造函数。
Demo
1 | 复制代码//Class.newInstance() |
使用场景:
如果使用接口模式,使用new创建一个门的对象,Door door = new WoodenDoor(),当以换成其他门,需要修改代码,Door door = new OtherDoor()。所以我们需要使用工厂模式,需要什么门就生产什么门,如果我们再使用newInstance()方法来生产,则只需要修改配置文件即可。
Field
通过Class对象获取到的Field对象之后,我们就可以自由的查看和设置对象的属性值。
关键方法:
- get(Object object)查看特定对象的属性值
- set(Object object, Object value)给特定对象设置属性
- setAccessible(boolean flag)让private成员拥有public权限
Demo
1 | 复制代码//获取Class对象 |
因为Constructor,Field,Method都继承自AccessibleObject类,所有都拥有setAccessible方法,个人感觉setAccessible有点窥探隐私的感觉,哈哈哈,不知道Class导演怎么看。
Method
通过Class对象获取到的Method对象之后,想都不用想啊,获取一个方法不调用它干嘛,所以我们最常用的操作应该就是invoke方法。
相信大家对invoke并不会陌生,因为很多的异常,最后都会定位到invoke方法。
1 | 复制代码java.lang.NullPointerException |
invoke(Object receiver, Object… args),可以分为两种,传递receiver参数表示调用特定对象的方法,传null表示调用静态方法。
1 | 复制代码//获取一个方法名为doSomesthing,参数类型为String的方法 |
最后说两句
本文只是对Clss对象以及reflect包下的对象进行简单的使用说明,关于反射的实现和原理,还有待于深入研究。例如AccessibleObject对象以及对应相关xxxAccessor的实现。
本文转载自: 掘金