不积跬步,无以至千里;不积小流,无以成江海。
反射功能介绍
反射功能如下:
1、对于任何一个类,通过反射,都能获取到他的属性和方法和方法
2、作用在运行状态中,也就是能够动态的获取和调用相关的属性和方法
获取类信息
获取类信息有以下三种方法;
1、Class.forName(“类完整的路径”) 例如:
Class cla = Class.forName("com.example.myapplication.ReflectionTest");
2、对象.getClass()
3、类名称.class
后两种方式比较简单,此处就不举例了
获取方法信息并调用方法
获取方法,通过getMethod实现,方法如下:
此方法接收的第一个参数为方法名,后面的可变参数为方法需要传入的参数类型。
例如有一个ReflectionTest类,代码如下:
public class ReflectionTest { String name = "张三"; public void printName(String[] arg ){ String name0 = (String)arg[0]; String name1= (String)arg[1]; Log.d("test",name0 + " " + name1 + " threadId:" + Thread.currentThread().getId() + " time:"+ System.currentTimeMillis()); } }
获取 printName方法,代码如下:
//获取类 Class cla = Class.forName("com.example.myapplication.ReflectionTest"); //获取方法 Method method = cla.getMethod("printName", String[].class);
调用该方法需要使用到 Method中的invoke方法,invoke方法如下:
public native Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
1、该方法是一个native方法Method
2、invoke方法第一个参数为调用这个方法的对象,后面的可变参数为Method方法需要传入的参数
例如调用上面的printName方法,代码如下:
method.invoke(test, (Object) new String[]{"test1", "test2"});
获取属性信息
获取属性信息常用到以下两个方法:
getDeclaredField(String name)
getField(String name)
这两个方法的区别在于getField(String name)只能获取到public类型的属性,而getDeclaredField(String name)非public属性也能够获取到
例如:
//获取属性 Field name = cla.getDeclaredField("name");
涉及到属性,就需要看一下对应的get和set方法
get(Object obj):获取属性值,参数obj为需要获取属性的对象
set(Object obj, Object value):设置属性值,参数obj为需要设置属性的对象,value参数为所设的参数值
例如:
ReflectionTest test = (ReflectionTest) cla.newInstance(); name.set(test, "李四");//设置属性值 name.get(test);//
需要注意的是,假如获取属性值是一个私有属性,那么在设置该属性的值之前,一定要先设置该属性的setAccessible方法为true,后续才能够成功的为属性设置值
例如:
name.setAccessible(true);
反射测试代码片段:
//获取类 Class cla = Class.forName("com.example.myapplication.ReflectionTest"); //获取方法 Method method = cla.getMethod("printName", String[].class); //获取属性 Field name = cla.getDeclaredField("name"); name.setAccessible(true); ReflectionTest test = (ReflectionTest) cla.newInstance(); name.set(test, "李四");//设置值 name.get(test);//获取值 //调用方法 method.invoke(test, (Object) new String[]{"test1", test.name});