AccessibleObject类的setAccessible方法有一个布尔参数的原因是什么?

时间:2013-04-26 07:05:38

标签: java reflection signature

我在反思中很新,我有一个疑问:

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

3 个答案:

答案 0 :(得分:15)

在你的一生中,你永远不会做setAccessible(false)。这是因为setAccessible不会永久地更改成员的可见性。当您使用method.setAccessible(true)之类的内容时,即使原始来源中的方法是私有,您也可以在 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 **/

  }

}

答案 1 :(得分:4)

场景:您已将Field.setAccessible(true),读取后的私有字段中的保护取消,并将字段返回到原始状态Field.setAccessible(false).

答案 2 :(得分:0)

//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));

}

}