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
无参构造
Class clazz = Class.forName("类的路径");
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();
有参构造
Class classType = Class.forName(classPath);
Constructor constructor = classType.getConstructor(intArgsClass);
constructor.setAccessible(true); // 压制 java 检查,防止当构造函数时 private 时拿不到
Object object = constructor.newInstance(intArgs);
说明
- 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( ) 即可,可不用反射
例子
调用了无参构造函数
private Object createEmployeeByClassPath(String classPath){
try {
Class cl = Class.forName(classPath);
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();
return object;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
如果是 private 的构造函数
// 获取 private 的构造函数
Class cl = Class.forName(classPath);
Constructor constructor = cl.getDeclaredConstructor();
constructor.setAccessible(true);
Object object = constructor.newInstance();
调用有参构造函数
private void createEmployeeByConstructor(String classPath, Class[] intArgsClass, Object[] intArgs){
try {
Class classType = Class.forName(classPath);
Constructor constructor = classType.getConstructor(intArgsClass);
constructor.setAccessible(true); // 压制 java 检查,防止当构造函数时 private 时拿不到
Object object = constructor.newInstance(intArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
2.通过反射调用方法 Method
获取方法
Class.getMethods() 返回自身和父类的方法
Class.getDeclaredMethods() 只返回自身的方法
获取指定的方法
// methodName 是方法名,intArgsClass 是方法签名参数类型
Method method = clazz.getDeclaredMethod(methodName, intArgsClass);
调用方法
method.invoke(Object, intArgs) // intArgs 是具体的参数类型
例子
获取方法
private void getMethods(Object object){
// 获取所有方法,包括父类的
Method[] methods = object.getClass().getMethods();
for (Method method : methods){
Log.i(TAG, "getMethods method " + method.toString());
}
// 至获取自身定义的方法
Method[] methods1 = object.getClass().getDeclaredMethods();
for (Method method : methods1){
Log.i(TAG, "getMethods method " + method.toString());
}
}
调用方法
// 反射调用方法
private void invokeMethod(Object object, String methodName, Class[] intArgsClass, Object[] intArgs){
try {
Class clazz = object.getClass();
Method method = clazz.getDeclaredMethod(methodName, intArgsClass);
method.setAccessible(true);
Object returnValue = method.invoke(object, intArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
3. 通过反射获取成员变量 Field
获取 Field
Fields[] fields = Class.getFields() // 获取这个类和它父类的 public 成员变量
Fields[] fields = Class.getDeclaredFields() //获取这个类和它父类的全部成员变量
设置成员变量的值
Class.getDeclaredField(fieldName) // 获取具体的成员变量
Field.setAccessible(true);
Field.set(object, value) // 设值
例子
获取成员变量
// 获取成员变量
private void getFields(Object object){
Field[] fields = object.getClass().getFields();
for (Field field : fields){
Class type = field.getType();
String name = field.getName();
}
}
获取具体的成员变量
private void getField(Object object, String fieldName){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object fieldVale = field.get(object);
String name = (String) fieldVale;
} catch (Exception e) {
e.printStackTrace();
}
}
设置成员变量的值
private void setFieldValue(Object object, String fieldName, Object value){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
} catch (Exception e){
e.printStackTrace();
}
}
4. 获取注解
Metho, Field, Constructor 都可以直接调用getAnnotationgetAnnotation(Class<> annotationType) 获取
使用注解的开源库都会用到 EeventBus, ARouter 等
private void getAnnotationMethod(Object object){
Method[] methods = object.getClass().getDeclaredMethods();
for (Method method: methods){
MyAnnotation annoType = method.getAnnotation(MyAnnotation.class);
if (annoType != null){
Log.i(TAG, "getAnnotationMethod name = " + method.getName());
}
}
}
5.获取修饰符
Metho, Field, Constructor 都可以直接调用 getModifier() 获取
Modifier 这个类可以分析这个返回值
private void getModifiers(Object object){
Field[] fields1 = object.getClass().getDeclaredFields();
for (Field field : fields1){
Class type = field.getType();
String name = field.getName();
printModifier(name, field.getModifiers());
}
}
private void printModifier(String name, int modifier){
String modifiers = Modifier.toString(modifier);
boolean isFinal = Modifier.isFinal(modifier);
}
6. 其他
setAccessible(true)
Metho, Field, Constructor 都可以设置 setAccessible(true), 压制 java 检查,防止 private 时拿不到
getConstructor 与 getDeclaredConstructor 的区别
- getDeclaredConstructor 可以返回 private 的构造函数,但是需要 Constructor.setAccessible(true), 配合一起使用
Class cl = Class.forName(classPath);
Constructor constructor = cl.getDeclaredConstructor();
constructor.setAccessible(true);
Object object = constructor.newInstance();
- getConstructor 只是返回 public 的构造函数
Class cl = Class.forName(classPath);
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();
7.完整的示例代码
ReflectActivity.java
/**
* 反射的
*/
public class ReflectActivity extends Activity {
private static final String TAG = "ReflectActivity";
private static final String CLASS_PATH = "com.yxhuang.myapplication.reflect.Employee";
private Employee mEmployee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reflect);
// createEmployeeByConstructor(CLASS_PATH, new Class[]{String.class, long.class}, new Object[]{"张三", 5000});
// Object object = createEmployeeByClassPath(CLASS_PATH);
// getMethods(object);
// invokeMethod(object, "setName", new Class[]{String.class}, new Object[]{"李四"});
// mEmployee = new Employee("李四", 5000, 22);
// mEmployee.setAddress("广东");
// getFields(mEmployee);
// getField(mEmployee, "mName");
// setFieldValue(mEmployee, "mName", "张三");
// getAnnotationMethod(mEmployee);
classInstance();
}
// 调用了无参构造函数
private Object createEmployeeByClassPath(String classPath){
try {
Class cl = Class.forName(classPath);
Constructor constructor = cl.getConstructor();
Object object = constructor.newInstance();
Employee employee = (Employee) object;
Log.i(TAG, "createEmployeeByClassPath " + employee.toString());
return object;
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Error" + e.getMessage());
}
return null;
// 获取 private 的构造函数
// Class cl = Class.forName(classPath);
// Constructor constructor = cl.getDeclaredConstructor();
// constructor.setAccessible(true);
// Object object = constructor.newInstance();
}
// 调用有参构造函数
private void createEmployeeByConstructor(String classPath, Class[] intArgsClass, Object[] intArgs){
try {
Class classType = Class.forName(classPath);
Constructor constructor = classType.getConstructor(intArgsClass);
constructor.setAccessible(true); // 压制 java 检查,防止当构造函数时 private 时拿不到
Object object = constructor.newInstance(intArgs);
Employee employee = (Employee) object;
Log.i(TAG, "createEmployeeByConstructor " + employee.toString());
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "createEmployeeByConstructor error " + e.getMessage());
}
}
private void getMethods(Object object){
// 获取所有方法,包括父类的
Method[] methods = object.getClass().getMethods();
for (Method method : methods){
Log.i(TAG, "getMethods method " + method.toString());
}
Log.i(TAG, " ----------------------------------------");
// 至获取自身定义的方法
Method[] methods1 = object.getClass().getDeclaredMethods();
for (Method method : methods1){
Log.i(TAG, "getMethods method " + method.toString());
}
}
// 反射调用方法
private void invokeMethod(Object object, String methodName, Class[] intArgsClass, Object[] intArgs){
try {
Class clazz = object.getClass();
Method method = clazz.getDeclaredMethod(methodName, intArgsClass);
method.setAccessible(true);
Object returnValue = method.invoke(object, intArgs);
Log.i(TAG, "invokeMethod returnValue ");
print(object);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "invokeMethod error " + e.getMessage());
}
}
// 获取成员变量
private void getFields(Object object){
Field[] fields = object.getClass().getFields();
for (Field field : fields){
Class type = field.getType();
String name = field.getName();
Log.i(TAG, " getFields type= " + type + " name= " + name);
}
Log.i(TAG, " ----------------------------------------");
// 获取方法的标识符
Field[] fields1 = object.getClass().getDeclaredFields();
for (Field field : fields1){
Class type = field.getType();
String name = field.getName();
Log.i(TAG, " getFields type= " + type + " name= " + name);
printModifier(name, field.getModifiers());
}
}
// 获取具体的成员变量
private void getField(Object object, String fieldName){
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object fieldVale = field.get(object);
String name = (String) fieldVale;
Log.i(TAG, " getField name= " + name);
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, " getField error= " + e.getMessage());
}
}
// 设置成员变量的值
private void setFieldValue(Object object, String fieldName, Object value){
Log.i(TAG, "before set field ");
print(object);
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
Log.i(TAG, "after set field ---- ");
print(object);
} catch (Exception e){
e.printStackTrace();
Log.i(TAG, " getField error= " + e.getMessage());
}
}
// 获取注解的
private void getAnnotationMethod(Object object){
Method[] methods = object.getClass().getDeclaredMethods();
for (Method method: methods){
MyAnnotation annoType = method.getAnnotation(MyAnnotation.class);
if (annoType != null){
Log.i(TAG, "getAnnotationMethod name = " + method.getName());
}
}
}
private void print(Object object){
Employee employee = (Employee) object;
Log.i(TAG, "print " + employee.toString());
}
private void printModifier(String name, int modifier){
String modifiers = Modifier.toString(modifier);
boolean isFinal = Modifier.isFinal(modifier);
Log.i(TAG, "name = " + name + " modifier= " + modifiers + " isFinal= " + isFinal);
}
// 不是用反射
private void classInstance(){
try {
Employee employee = Employee.class.newInstance();
Log.i(TAG, "classInstance " + employee.toString());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Employee.java
/**
* Created by yxhuang
* Date: 2018/11/10
* Description:
*/
public class Employee extends Person {
private static final String TAG = "Employee";
private String mName;
private long mSalary;
public String mAddress;
public Employee(){
super(20);
Log.i(TAG, "调用 Employee 无参构造函数");
}
public Employee(String name, long salary, int age) {
super(age);
mName = name;
mSalary = salary;
Log.i(TAG, "调用 Employee 有参参构造函数 name= " + name + " salary= " + salary);
}
public String getName() {
return mName;
}
@MyAnnotation
public void setName(String name) {
Log.i(TAG, "set name " + name);
mName = name;
}
public long getSalary() {
return mSalary;
}
@MyAnnotation
public void setSalary(long salary) {
mSalary = salary;
}
public String getAddress() {
return mAddress;
}
public void setAddress(String address) {
mAddress = address;
}
@Override
public String toString() {
return "Employee{" +
"mName='" + mName + '\'' +
", mSalary=" + mSalary +
", mAag=" + mAag +
'}';
}
}
Person.java
public class Person {
public int mAag;
public Person(int aag) {
mAag = aag;
}
}
MyAnnotation.java
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MyAnnotation {
}