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

Shr*_*ari 5 java reflection signature

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

public void setAccessible(boolean flag) throws SecurityException
Run Code Online (Sandbox Code Playgroud)

此方法有一个boolen参数标志,表示任何字段或方法的新可访问性.
例如,如果我们尝试private从类外部访问类的方法,那么我们使用获取方法getDeclaredMethod并将可访问性设置为true,因此可以调用它,如:method.setAccessible(true);
现在在我们应该使用的场景中method.setAccessible(false);,例如它可以在有public方法时使用,我们将可访问性设置为false.但那有什么需要呢?我的理解清楚了吗?
如果没有使用method.setAccessible(false)那么我们可以改变方法签名,如:

public void setAccessible() throws SecurityException
Run Code Online (Sandbox Code Playgroud)

mic*_*oon 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 **/

  }
Run Code Online (Sandbox Code Playgroud)

}


Evg*_*eev 5

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

  • 您可以执行此操作,但这不会产生任何效果,因为您不会通过再次将其设置为 false 来保护可访问性,因为任何客户端都可以随时获取字段实例并再次使用 setAccessible(true) 来使用该字段。此外,setAccessible 不会永久改变字段的可访问性,也不会以非反射方式改变,因此您可以保护它免受客户端以非反射方式使用该字段的影响。 (12认同)