反射知识

反射是可以在一个类运行的时候获得类的信息的机制,可以获取到在编译期不能获取到的类的信息。对于任意的对象,都能获取方法和属性,因为类的信息是保存在Class对象中的,而这个Class对象是在程序运行时类加载器(ClassLoader)动态加载的。
当类加载器装载了类后,动态获取Class对象的信息以及动态操作Class对象的属性和方法的功能称为Java的反射机制。

反射机制需要使用的类:

java.lang.Class
java.lang.reflect.Constructor
java.lang.reflect.Field
java.lang.reflect.Method
java.lang.reflect.Modifier   //访问修饰符信息

1.获取Class对象的三种方式

①Class c1=Class.forName("com.xxx.xxx")
会让ClassLoader装载类,进行类的初始化。

②Class c2=Reflect.class
ClassLoader装载进内存,不进行初始化

③Class c3=new Reflect().getClass()
返回类对象运行时真正所指的对象,所属类型的Class对象。

2.获取Class对象后,就可以通过newInstance()获取类对象。
使用newInstance()方法只能创建无参构造出来的对象。

Object o = c1.newInstance();
TestEntity t1= (TestEntity) o;
t1.setName("啦啦啦");

3.如果构造器中有参数,那么就要先获取到构造器后,然后创建对象,并传递参数

Constructor constructor1 = c1.getConstructor(String.class, int.class);
Object o1 = constructor1.newInstance("水水", 12);
TestEntity t3= (TestEntity) o1;
Log.e("TAG", "t3==="+t3);

4.获取类中属性值,属性名,修饰符,方法

Field nameField = c1.getDeclaredField("name");

//取消封装,特别是可以取消私有字段的访问限制,它并不是将方法权限改为public,而是取消java的权限控制检查,即便是public修饰符,其accessible也是false。

nameField.setAccessible(true);

Object o = c1.newInstance();

//设置属性值

nameField.set(o,"大美");

//获取属性值

Object nameStr = nameField.get(o);

//获取属性名

String name = nameField.getName();

//设置属性修饰符

int modifiers = nameField.getModifiers();
String modifier = Modifier.toString(modifiers);
Log.e("TAG", "修饰符=="+Modifier.isPrivate(modifiers));

//调用方法 第二个参数是可变参数,表示参数的类型
//getDeclaredMethod()获取的是自身声明的所有的方法,包括public,protected,private方法,

Method setNameF = c1.getDeclaredMethod("setName", String.class);
setNameF.invoke(o,"小妹");

5.反射获取属性

getField:  能获取本类和超类中public修饰的属性。
getDeclaredField:   只能获取到本类中public protected private修饰的属性
getFields:  能获取本类和超类中public修饰的属性。
getDeclaredFields:   只能获取到本类中public protected private修饰的属性

如果是获取到超类中的属性,那么就需要使用getSuperclass方法获取父类对象,然后通过父类对象调用getDeclaredField获取属性。
在父类中定义boolean值sex,然后反射获取

Field sex = c1.getSuperclass().getDeclaredField("sex");
sex.setAccessible(true);
sex.set(o,true);

6.反射获取方法,用法和上面的相同

getMethod
getDeclaredMethod
getMethods
getDeclaredMethods

7.反射获取构造器,下面方法都不能调用父类的任何构造器。

getConstructor  获取本类public
getDeclaredConstructor  获取本类public  private protected
getConstructors  获取本类public
getDeclaredConstructors  获取本类public  private protected

反射获取对象,一般有两种方法Class.newInstance()和Constructor.newInstance()。不同的是Class.newInstance()必须无参。但是Constructor.newInstance()却没有限制。

8.调用静态方法

Method test = c1.getDeclaredMethod("test");

//重要的是,在invoke中传null

test.invoke(null);

9.joor反射库的使用

github:
https://github.com/jOOQ/jOOR

中文 README:
https://github.com/tianzhijiexian/Android-Best-Practices/blob/master/2015.9/reflect/README - chinese.md

猜你喜欢

转载自blog.csdn.net/yuezheyue123/article/details/88566209