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的运行时优化无法进行。