一般当我们无法直接拿到 目标对象,或者方法的时候,可以通过反射来实现调用
setAccessible
public void setAccessible(boolean flag) throws SecurityException
将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
使用了method.setAccessible(true)后 性能有了20倍的提升
Accessable属性是继承自AccessibleObject 类. 功能是启用或禁用安全检查
//也可以通过反射来调用目标方法
try {
Class<?> clazz = Class.forName("com.womai.push.WMPushReceiverUtils");
Method onNotificationOpened = clazz.getDeclaredMethod("onNotificationOpened",Context.class, String.class);
//将此对象的 accessible 标志设置为指示的布尔值。
//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
//值为 false 则指示反射的对象应该实施 Java 语言访问检查。
onNotificationOpened.setAccessible(true);
onNotificationOpened.invoke(clazz,context,jsonArray2JsonObject(extras.get("pushMsg").toString()));
} catch (Exception e) {
e.printStackTrace();
}
反射调用的例子
Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
Object obj = cls.newInstance() //反射实例化对象
Constructor<?> cons = cls.getConstructor(String.class, int.class);//获得构造方法
Method m3 = cls.getDeclaredMethod("getName"); //获得get方法
Field nameField = cls.getDeclaredField("name"); // 获得name属性
Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
Constructor<?> cons = cls.getConstructor(String.class, int.class);
Object obj = cons.newInstance("张三", 20); // 为构造方法传递参数
System.out.println(obj); // Person [name=张三, age=20]
Method m = cls.getDeclaredMethod("say"); //示爱y是自己在类中自定义的方法
m.invoke(obj);//输出123456789,这个obj可以是new出来的或newInstance出来的
Object obj = Class.forName("Person").newInstance();
Field nameField = cls.getDeclaredField("name"); // 获得name属性
nameField.setAccessible(true); //解除封装
nameField.set(obj, "张三"); // Person对象.name = "张三"
System.out.println(nameField.get(obj)); // Person对象.name