Java反射是可访问的方法

DPM*_*DPM 11 java reflection

我正在学习反思.当我执行以下代码时:

package main;

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws NoSuchFieldException, SecurityException {

        Base firstBase = new Base();
        Field firstBaseField = firstBase.getClass().getDeclaredField("protectedBuffer");
        System.out.println(firstBaseField.isAccessible());

    }
}
Run Code Online (Sandbox Code Playgroud)

这是基类:

package main;

public class Base {

    private StringBuffer buffer;
    protected StringBuffer protectedBuffer;
    public StringBuffer buffer2;

}
Run Code Online (Sandbox Code Playgroud)

结果是错误的.但这不是真的,因为我可以这样访问protectedBuffer:firstBase.protectedBuffer

Joh*_*ohn 11

这是因为你没有测试Field protectedBuffer是否可访问firstBaseField.isAccessible();

这里发生的是你检查其值AccessibleObject是Field的基类.此标志不会告诉您java访问修饰符是否可以访问该字段,它会告诉您当前是否忽略这些修饰符.

当你弄错firstBaseField.isAccessible()它只是意味着java访问规则仍然存在并且不被反射机制覆盖.

setAccessible()

将此对象的可访问标志设置为指示的布尔值.值true表示反射对象在使用时应禁止Java语言访问检查.值false表示反射对象应强制执行Java语言访问检查.

编辑

要测试java访问修饰符是否可以访问该字段,您可以尝试访问它并捕获IllegalAccessException,如下例所示.

Field field = instance.getClass().getDeclaredField("someField");
//  IllegalAccessException
field.get(instance);
Run Code Online (Sandbox Code Playgroud)


Tag*_*eev 5

您错误地理解了这个可访问标志。根据文档,当accessible为true时,所有访问检查都会被绕过(您可以使用此字段或方法,Java不会检查它是否是公共的)。当accessible为假时,访问检查起作用。正如文档中所写,它false默认适用于任何 AccessibleObject(甚至public字段或方法)。


SJX*_*SJX 5

从 Java 9 开始,该isAccessible方法已被弃用。你可以用canAccess它代替。