一般當我們無法直接拿到 目標對象,或者方法的時候,可以通過反射來實現調用
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