java反射机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息。就是说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
Java反射相关的API在包java.lang.reflect中。
针对任何您想探勘的class,必须先为它产生一个Class object,接下来才能由后者调用Reflection APIs。
Class object的获得
1.getClass()
2.Class.getSuperclass()
3.Class.forName()
4.xxx.class
5.xxx.TYPE
Java classes各成份所对应的Reflection APIs
1.运行时生成instances
通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例 。
public Constructor<T> getConstructor(Class<?>... parameterTypes) | 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法 |
public Constructor<?>[] getConstructors() | 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法 |
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) | 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法 |
public Constructor<?>[] getDeclaredConstructors() | 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。它们是公共、保护、默认(包)访问和私有构造方法 |
2.运行时调用methods
public Method getMethod(String name,Class<?>... parameterTypes) | 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法 |
public Method[] getMethods() | 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法 |
public MethodgetDeclaredMethod(Stringname,Class<?>... parameterTypes) | 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法 |
public Method[] getDeclaredMethods() | 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法 |
通过反射获取类Method对象,调用该对象的Invoke方法调用函数。
- Class<?> classType = ExtendType.class;
- Object inst = classType.newInstance();
- Method logMethod = classType.<strong>getDeclaredMethod</strong>("Log", String.class);
- logMethod.invoke(inst, "test");
若调用private函数,需要设置权限,需要设置Accessible为true。
logMethod.setAccessible(true);
3.获取类的fields
通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。
public Field getField(String name) | 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段 |
public Field[] getFields() | 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段 |
public FieldgetDeclaredField(Stringname) | 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 |
public Field[] getDeclaredFields() | 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段 |
getFields返回的是申明为public的属性,包括父类中定义,
getDeclaredFields返回的是指定类定义的所有定义的属性,不包括父类的。
- Class<?> classType = ExtendType.class;
- Object inst = classType.newInstance();
- Field intField = classType.getField("pubIntExtendField");
- intField.setInt(inst, 100);
- int value = intField.getInt(inst);
4.新建类的实例
(1)调用无自变量ctor。
调用类的Class对象的newInstance方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败。
Class<?> classType = ExtendType.class;
Object inst = classType.newInstance();
调用默认Constructor对象的newInstance方法
Class<?> classType = ExtendType.class;
Constructor<?> constructor1 = classType.getConstructor();
Object inst = constructor1.newInstance();
(2)调用带参数ctor
调用带参数Constructor对象的newInstance方法。
Constructor<?> constructor2 =classType.getDeclaredConstructor(int.class, String.class);
Object inst = constructor2.newInstance(1, "123");