[英]java.lang.NullPointerException: Cannot invoke "java.lang.reflect.AccessibleObject.setAccessible(boolean)" because "ao" is null
[英]What is the reason behind setAccessible method of AccessibleObject class have a boolean parameter?
我在Reflection中非常陌生,我對此有疑問:
public void setAccessible(boolean flag) throws SecurityException
此方法具有boolen
參數標志,該標志指示任何字段或方法的新可訪問性。
例如,如果嘗試從類外部訪問類的private
方法,則可以使用getDeclaredMethod
獲取該方法並將可訪問性設置為true
,以便可以調用它,例如: method.setAccessible(true);
現在在哪種情況下,我們應該使用method.setAccessible(false);
,例如,當存在public
方法並且我們將可訪問性設置為false時,可以使用它。 但是,這有什么需要? 我的理解清楚嗎?
如果不使用method.setAccessible(false)
那么我們可以像下面這樣更改方法簽名:
public void setAccessible() throws SecurityException
可能您一生都不會做setAccessible(false)
。 這是因為setAccessible不會永久更改成員的可見性。 當您使用諸如method.setAccessible(true)
之類的方法時,即使原始源中的方法是private,您也可以對此 method
實例進行后續調用。
例如考慮一下:
A.java
*******
public class A
{
private void fun(){
....
}
}
B.java
***********
public class B{
public void someMeth(){
Class clz = A.class;
String funMethod = "fun";
Method method = clz.getDeclaredMethod(funMethod);
method.setAccessible(true);
method.invoke(); //You can do this, perfectly legal;
/** but you cannot do this(below), because fun method's visibilty has been
turned on public only for the method instance obtained above **/
new A().fun(); //wrong, compilation error
/**now you may want to re-switch the visibility to of fun() on method
instance to private so you can use the below line**/
method.setAccessible(false);
/** but doing so doesn't make much effect **/
}
}
場景:使用Field.setAccessible(true),
刪除了私有字段的保護,對其進行了讀取,然后使用Field.setAccessible(false).
將字段恢復為原始狀態Field.setAccessible(false).
//create class PrivateVarTest { private abc =5; and private getA() {sop()}}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PrivateVariableAcc {
public static void main(String[] args) throws Exception {
PrivateVarTest myClass = new PrivateVarTest();
Field field1 = myClass.getClass().getDeclaredField("a");
field1.setAccessible(true);
System.out.println("This is access the private field-"
+ field1.get(myClass));
Method mm = myClass.getClass().getDeclaredMethod("getA");
mm.setAccessible(true);
System.out.println("This is calling the private method-"
+ mm.invoke(myClass, null));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.