Java反射机制
2018-03-07 本文已影响1人
海晨忆
个人博客:haichenyi.com。感谢关注
简介
在运行过程中,对任意一个类,都能知道这个类的所有属性和方法。对于任一个对象,都能调用他的任意一个方法和属性。这种动态获取信息以及动态调用对象的方法称为java语言的反射机制
用法
我这里就列出我常用的两个方法私有类和变量
方法Methods
方法 | 用途 |
---|---|
getDeclaredMethods() | 获取当前类的所有方法,包括public/private/protected/default修饰的方法 |
getDeclaredMethod(String name, Class<?>... parameterTypes) | 获取当前类的某一个方法,包括public/private/protected/default修饰的方法 |
getMethods() | 获取当前类和所继承父类的public标识的所有方法,仅仅包括public |
getMethod(String name, Class<?>... parameterTypes) | 获取当前类和所继承父类的public标识的某一个方法,仅仅包括public |
上面就是两个类型的方法,一个是只获取当前类的方法,获取当前类的方法,包括所有类型的方法:public/private/protected/default。还有一个是获取当前类和所继承的父类的方法,仅仅包括public修饰的方法。
调用方式
//在TakePhotoActivity.class类中有两个重载方法,一个无参,一个有一个String类型的参数
private void myTest(){
Log.v("WZ","myTest无参");
}
private void myTest(String msg){
Log.v("WZ","myTest有参");
}
调用无参的方法
TakePhotoActivity takePhotoActivity = new TakePhotoActivity();//new 一个类对象
try {
Class<? extends TakePhotoActivity> aClass1 = takePhotoActivity.getClass();//通过getClass方法获取类对象
//Class<?> aClass = Class.forName("com.haichenyi.mytakephoto.TakePhotoActivity");//通过路径获取Class对象
Method myTest = aClass1.getDeclaredMethod("myTest");
myTest.setAccessible(true);//参数值为true,禁止访问控制检查
myTest.invoke(takePhotoActivity);//执行私有方法
} catch (Exception e) {
e.printStackTrace();
Log.v("WZ", e.getMessage());
}
调用有参的方法
TakePhotoActivity takePhotoActivity = new TakePhotoActivity();//new 一个类对象
Class[] arr = new Class[]{String.class};
try {
Class<? extends TakePhotoActivity> aClass1 = takePhotoActivity.getClass();//通过getClass方法获取类对象
//Class<?> aClass = Class.forName("com.haichenyi.mytakephoto.TakePhotoActivity");//通过路径获取Class对象
Method myTest = aClass1.getDeclaredMethod("myTest",arr);
myTest.setAccessible(true);//参数值为true,禁止访问控制检查
myTest.invoke(takePhotoActivity,"s");//执行私有方法
} catch (Exception e) {
e.printStackTrace();
Log.v("WZ", e.getMessage());
}
有参的方法,在获取方法的时候,传一个Class[]数组,里面的值就是参数类型的类。或者还有另一种传的方法,前面获取方法的时候:
- 获取方法的时候,无参的传一个空的Class[],有参就传有值的Class[]数组
- 执行方法的时候,无参的传一个空的Object[],有参就传有值的Object[]数组,至于传的值随便写,类型一样就行
变量Field
方法 | 用途 |
---|---|
getDeclaredFields() | 获取当前类的所有类型的全局变量,包括public/private/protected/default修饰的变量 |
getDeclaredField(String name) | 获取当前类的某一个类型的全局变量,包括public/private/protected/default修饰的变量 |
getFields() | 获取当前类和继承父类的所有用public修饰的变量 |
getField(String name) | 获取当前类和继承父类的某一个用public修饰的变量 |
调用方式
//在TakePhotoActivity里面定义
private int flag;
获取变量
TakePhotoActivity takePhotoActivity = new TakePhotoActivity();//new 一个类对象
try {
Class<? extends TakePhotoActivity> aClass1 = takePhotoActivity.getClass();//通过getClass方法获取类对象
//Class<?> aClass = Class.forName("com.haichenyi.mytakephoto.TakePhotoActivity");//通过路径获取Class对象
Field flag = aClass.getDeclaredField("flag");
flag.setAccessible(true);
Object o = flag.get(takePhotoActivity);//这里就获取到了对象
...//做你自己的逻辑处理
} catch (Exception e) {
e.printStackTrace();
Log.v("WZ", e.getMessage());
}
设置变量的值
//获取变量的值跟上面一样
flag.set(takePhotoActivity,10);//这样写会改变TakePhotoActivity中flag的值
工具类
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Author: 海晨忆.
* Date: 2018/3/6
* Desc: 反射工具类
*/
public class ReflectionUtil {
/***
* 获取私有成员变量的值
*
*/
public static Object getValue(Object instance, String fieldName)
throws IllegalAccessException, NoSuchFieldException {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true); // 参数值为true,禁止访问控制检查
return field.get(instance);
}
/***
* 设置私有成员变量的值
*
*/
public static void setValue(Object instance, String fileName, Object value)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field field = instance.getClass().getDeclaredField(fileName);
field.setAccessible(true);
field.set(instance, value);
}
/***
* 访问私有方法
*
*/
public static Object callMethod(Object instance, String methodName, Class[] classes, Object[] objects)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Method method = instance.getClass().getDeclaredMethod(methodName, classes);
method.setAccessible(true);
return method.invoke(instance, objects);
}
}