Java反射机制
反射
反射:就是将类的各个组成部分封装为其他对象,是框架设计的灵魂。
我们在程序运行过程中,操作通过反射得到的对象,可以实现解耦,可以提高程序的可扩展性。
- 成员变量 –> Field
- 构造方法 –> Constructor
- 成员方法 –> Method
Java代码三个阶段
源码阶段(包括字节码) –> Class类对象阶段 –> RunTime运行时阶段
源码到Class类对象这个过程就是反射
获取Class对象
一个类字节码文件在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
Class.forName("全类名")
:将字节码文件加载进内存,返回Class对象- 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
类名.class
:通过类名的属性class获取- 多用于参数的传递
对象.getClass()
:getClass()
方法在Object类中定义着。- 多用于对象的获取字节码的方式
例子
1 | public class Person { |
Class对象常用方法
- 获取成员变量们
Field[] getFields()
:获取所有public修饰的成员变量Field getField(String name)
获取指定名称的 public修饰的成员变量Field[] getDeclaredFields()
获取所有的成员变量,不考虑修饰符Field getDeclaredField(String name)
获取指定名称的成员变量
- 获取构造方法们
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(Class<?>... parameterTypes)
- 传入构造方法对应形参的Class对象。如:
int.class, String.class
- 传入构造方法对应形参的Class对象。如:
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
- 获取成员方法们:
Method[] getMethods()
Method getMethod(String name, Class<?>... parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
- 获取类上注解:
Annotation[] getAnnotations()
<A extends Annotation> A getAnnotation(Class<A> annotationClass)
- 获取全类名:
String getName()
Field对象
成员变量对象
- 设置值:
void set(Object obj, Object value)
- 获取值:
get(Object obj)
- 忽略访问权限修饰符的安全检查:
setAccessible(true)
:暴力反射, 设置后访问权限修饰符不起作用
例子
1 | Field[] fields = cls1.getDeclaredFields(); |
Constructor对象
构造方法对象
T newInstance(Object... initargs)
: 创建一个对象
例子
1 | Constructor constructor = cls1.getConstructor(String.class); |
Method对象
成员方法对象
- 执行方法:
Object invoke(Object obj, Object... args)
- 获取方法名称:
String getName()
:获取方法名
1 | Method[] methods = cls1.getMethods(); |
案例
写一个”框架”,实现在不改变任何代码的前提下,通过改变配置文件,来创建任意类的对象,并且执行其中任意方法。
配置文件
1 | # src/conf.properties |
代码
1 | Properties prop = new Properties(); |