#Java 反射
Java 反射是在 java.lang.reflect 包类,包含 Constructor、Method、Field 的反射。
域 | 涉及的方法 | 说明 |
---|---|---|
创建类 Constructor | Class.getConstructor( ) Constructor.newInstance(args) | newInstance( ) 方法可以为无参调用 |
方法 Method | Class.getMethods( ) Class.getDeclaredMethods( ) | getMethods( ) 返回自身和父类的方法; getDeclaredMethods( ) 只返回自身的方法 |
变量 Field | Class.getFields( ) Class.getDeclaredFields( ) | getFields() 获取这个类和它父类的 public 成员变量; getDeclaredFields() 获取这个类和它父类的全部成员变量 |
1. 通过反射创建类 Constructor
无参构造
1 | Class clazz = Class.forName("类的路径"); |
有参构造
1 | Class classType = Class.forName(classPath); |
说明
- getConstructor(Class[])Class[] 是构造函数参数类型
例如 Employee(String name, long salary), 则 Class[] 就是 new Class[]{String.class, long.class}
- onstructor.newInstance(Object[]) Object[] 是构造函数的具体参数值
例如 Employee(String name, long salary) 则 Object[] 就是 new Object[]{“张三”, 5000}
- 如果是无参构造函数使用 Class.newInstance( ) 即可,可不用反射
例子
调用了无参构造函数
1 | private Object createEmployeeByClassPath(String classPath){ |
如果是 private 的构造函数
1 | // 获取 private 的构造函数 |
调用有参构造函数
1 | private void createEmployeeByConstructor(String classPath, Class[] intArgsClass, Object[] intArgs){ |
2.通过反射调用方法 Method
获取方法
1 | Class.getMethods() 返回自身和父类的方法 |
获取指定的方法
1 | // methodName 是方法名,intArgsClass 是方法签名参数类型 |
调用方法
1 | method.invoke(Object, intArgs) // intArgs 是具体的参数类型 |
例子
获取方法
1 | private void getMethods(Object object){ |
调用方法
1 | // 反射调用方法 |
3. 通过反射获取成员变量 Field
获取 Field
1 | Fields[] fields = Class.getFields() // 获取这个类和它父类的 public 成员变量 |
设置成员变量的值
1 | Class.getDeclaredField(fieldName) // 获取具体的成员变量 |
例子
获取成员变量
1 | // 获取成员变量 |
获取具体的成员变量
1 | private void getField(Object object, String fieldName){ |
设置成员变量的值
1 | private void setFieldValue(Object object, String fieldName, Object value){ |
4. 获取注解
Metho, Field, Constructor 都可以直接调用getAnnotationgetAnnotation(Class<> annotationType) 获取
使用注解的开源库都会用到 EeventBus, ARouter 等
1 | private void getAnnotationMethod(Object object){ |
5.获取修饰符
Metho, Field, Constructor 都可以直接调用 getModifier() 获取
Modifier 这个类可以分析这个返回值
1 | private void getModifiers(Object object){ |
6. 其他
setAccessible(true)
Metho, Field, Constructor 都可以设置 setAccessible(true), 压制 java 检查,防止 private 时拿不到
getConstructor 与 getDeclaredConstructor 的区别
- getDeclaredConstructor 可以返回 private 的构造函数,但是需要 Constructor.setAccessible(true), 配合一起使用
1 | Class cl = Class.forName(classPath); |
- getConstructor 只是返回 public 的构造函数
1 | Class cl = Class.forName(classPath); |
7.完整的示例代码
ReflectActivity.java
1 | /** |
Employee.java
1 | /** |
Person.java
1 | public class Person { |
MyAnnotation.java
1 | (RetentionPolicy.RUNTIME) |