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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16230601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:18:00  来源:igfitidea点击:

What is the reason behind setAccessible method of AccessibleObject class have a boolean parameter?

javareflectionsignature

提问by Shreyos Adikari

I am very new in Reflection and I have a doubt like:

我对 Reflection 很陌生,我有一个疑问:

public void setAccessible(boolean flag) throws SecurityException

This method has a boolenparameter flag, which indicates the new accessibility of any fields or methods.
For an example if we are try to access a privatemethod of a class from outside the class then we fetch the method using getDeclaredMethodand set the accessibility as true, so it can be invoked, like: method.setAccessible(true);
Now in which scenario we should use method.setAccessible(false);, for an example it can be used when there is a publicmethod and we set the accessibility as false. But what is the need of that? Is my understanding clear?
If there is no use of method.setAccessible(false)then we can change the method signature like:

此方法有一个boolen参数标志,它指示任何字段或方法的新可访问性。
例如,如果我们尝试private从类外部访问类的方法,那么我们获取方法 usinggetDeclaredMethod并将可访问性设置为true,以便可以调用它,例如:method.setAccessible(true);
现在我们应该在哪种情况下使用method.setAccessible(false);,例如当有public方法并且我们将可访问性设置为false时可以使用。但这有什么必要呢?我的理解清楚吗?
如果没有使用,method.setAccessible(false)那么我们可以更改方法签名,如:

public void setAccessible() throws SecurityException

采纳答案by Evgeniy Dorofeev

Scenario: you removed protection from a private field with Field.setAccessible(true),read it and returned the field into original state with Field.setAccessible(false).

场景:您通过Field.setAccessible(true),read从私有字段中删除了保护,并将该字段返回到原始状态Field.setAccessible(false).

回答by mickeymoon

Probably you would never do setAccessible(false)in your entire life. This is because setAccessible doesn't the change the visiblity of the a member permanently. When you to something like method.setAccessible(true)you are allowed to make subsequent calls on thismethodinstance even if the method in the original source is private.

可能你一辈子都做不到setAccessible(false)。这是因为 setAccessible 不会永久更改成员的可见性。当您使用类似的方法时,即使原始源中的方法是私有的,method.setAccessible(true)您也可以对此method实例进行后续调用。

For example consider this:

例如考虑这个:

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 **/

  }

}

}

回答by RamChandra Bhakar

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

}

}