Java反射是可访问的方法



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

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());
    }
}

这是基本类:

package main;
public class Base {
    private StringBuffer buffer;
    protected StringBuffer protectedBuffer;
    public StringBuffer buffer2;
}

结果是错误的。但这不是真的吗,因为我可以用这种方式访问protectedBufferfirstBase.protectedBuffer

这是因为在执行firstBaseField.isAccessible(); 时没有测试字段protectedBuffer是否可访问

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

当您在firstBaseField.isAccessible()上得到false时,这仅仅意味着java访问规则仍然存在,并且不会被反射机制覆盖。

setAccessible((

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

编辑

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

Field field = instance.getClass().getDeclaredField("someField");
//  IllegalAccessException
field.get(instance);

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

从Java 9开始,isAccessible方法已被弃用。您可以改用canAccess

默认情况下,使用Class#getDeclaredField(String name)检索的所有Fields都将accessible标志设置为false。对于public字段buffer2,也会得到false。

Field类是AccessibleObject:的一个子类

默认情况下,反射对象不可访问

相关内容

  • 没有找到相关文章

最新更新