Android JAVA 反射

1、反射的作用及应用场景

JAVA的反射机制是在运行状态中,对于任意一个类,都可以知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法;這中动态获取信息级动态调用对象的方法的功能称为 java语言的反射机制。

简单来说,私有方法,谷歌的隐藏接口(hide)这些不能被直接掉用的;就可以通过反射进行调用

2、反射的原理

代码在编写时,可以调用编译到SDK中的接口,而隐藏的接口是不会编译到SDK中去的,所以无法直接使用;但是,每个class都有对应的Class对象,当编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表达这个类的类型信息;反射就是通过这个类反向获取到这个类的所有属性和方法的。

3、反射的用法及案例

java中Class三种获取方式:

//使用Class类的而静态方法forName(),用类的名字获取一个Class实列

Class<?>  zzClass = Class.forName(com.zz.zhangzhuo);

类名都无法找到,无法new对象时,使用此方法

//利用对象调用getClass()方法获取该对象的Class实例

Book book = new Book();

Class<? extends Book> bookClass  = book.getClass();

类名可以找到,但是里面想要调的方法是私有的,可以用这种方式获取Class

//运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例

Class<Book> bookClass = Book.class;

Class<Interger> type = Integer.TYPE;

私有方法调用:

如Book类中有私有方法private String getName(int i),无法直接调用,我们使用反射调用获取

Book book = new Book();

Class<? extends Book> bookClass  = book.getClass();

Object book = bookClass.newInstance();//通过调用默认(及无参数)的构造函数创建一个新的实例

Method meth1 = bookClass .getDeclaredMethod(“getName”, int.class);//获取反射的私有方法

meth1.setAccessbale(true);//设置可以访问私有域

String name = (String)meth1.invoke(book, 2019);//对象book,参数2019,调用私有方法返回字符串,反射调用无法检测存在的异常,所以需要try catch保护,此处省略。

隐藏api调用

最近做的项目,是一个没有界面只有服务的项目,由于安卓机制,总是在各种情况下被清理掉,导致程序运行失败;

fwk底层做适配,有接口用来保活,但是接口是hide级别的,无法直接调用,类名都无法同故宫import方法识别,sdk

中没有可供应用使用的接口,是隐藏的,所以通过反射调用

项目案例:

Class<?> clazz = Class.forName("com.xxx.xxxx");

Method meth1 = class.getMethod("getInstance");

Object instance = meth1.invoke(clazz);

Method meth2 = class.getMethod("applyforResource",  String.class, int.class);

meth2.invoke(instance, "apply for sava", 30*60);

4、反射的优缺点

反射优点:

1、可以调用私有方法、变量

2、可以调用隐藏api接口

3、有助于模块解耦,如上面项目案例,如果接口可以直接调用,与底层的耦合大,反射可以直接使用的包名字符串进行调用

反射缺点:

安全问题:反射可以获取到类对应的所有方法和属性,如果存在外部调用的情况,可能出现超出预期的调用,从而导致安全风险

性能问题:无论是通过字符串获取Class、Method还是Field,都需要JVM的动态链接机制动态的进行解析和匹配,势必造成性能开销。每一次的反射调用都会造成Java安全机制进行额外的安全性验证,造成性能开销。反射代码使得许多JVM的运行时优化无法进行。

猜你喜欢

转载自blog.csdn.net/zhangzhuo1024/article/details/87789693