簡體   English   中英

AccessibleObject類的setAccessible方法具有布爾參數的原因是什么?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM