java - field.setAccessible(false) 对非私有(private)字段的影响

标签 java reflection

field.setAccessible(false) 对非私有(private)字段有什么影响?

我预计该成员的访问会被拒绝,但事实并非如此!

我试图深入研究源代码,但在某些时候( Field#getFieldAccessor(Object) )我不知道发生了什么。

我为这种情况创建了一个特殊的类:

public class DemoObject {

    public Object publicMember = new Object();
    protected Object protectedMember = new Object();
    Object defaultMember = new Object();
    private Object privateMember = new Object();
    public final Object publicfinalMember = new Object();
    protected final Object protectedfinalMember = new Object();
    final Object defaultfinalMember = new Object();
    private final Object privatefinalMember = new Object();

}

并创建了一个演示:

import java.lang.reflect.Field;

public class MyMain {

    public static void main(final String[] args) {

        DemoObject object = new DemoObject();

        System.out.println("'reflective' member access after field.setAccessible(false)");
        for (Field field : object.getClass().getDeclaredFields()) {
            field.setAccessible(false);
            try {
                System.out.println(field.getName() + ": " + field.get(object));
                // only throws exception for the privateMember and privatefinalMember
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        System.out.println("'reflective' member access after field.setAccessible(true)");
        for (Field field : object.getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);
                System.out.println(field.getName() + ": " + field.get(object));
                // throws no exception
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

}

输出:

'reflective' member access after field.setAccessible(false)
publicMember: java.lang.Object@e9bfee2
protectedMember: java.lang.Object@237aaeec
defaultMember: java.lang.Object@4b721a26
java.lang.IllegalAccessException: Class MyMain can not access a member of class DemoObject with modifiers "private"
    at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
    at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
    at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
    at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
    at java.lang.reflect.Field.get(Unknown Source)
    at MyMain.main(MyMain.java:13)
publicfinalMember: java.lang.Object@7c30cd64
protectedfinalMember: java.lang.Object@67fc9fee
defaultfinalMember: java.lang.Object@7a67f797
java.lang.IllegalAccessException: Class MyMain can not access a member of class DemoObject with modifiers "private final"
    at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
    at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
    at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
    at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
    at java.lang.reflect.Field.get(Unknown Source)
    at MyMain.main(MyMain.java:13)
'reflective' member access after field.setAccessible(true)
publicMember: java.lang.Object@e9bfee2
protectedMember: java.lang.Object@237aaeec
defaultMember: java.lang.Object@4b721a26
privateMember: java.lang.Object@424c2849
publicfinalMember: java.lang.Object@7c30cd64
protectedfinalMember: java.lang.Object@67fc9fee
defaultfinalMember: java.lang.Object@7a67f797
privatefinalMember: java.lang.Object@15e8f2a0

最佳答案

根据 AccessibleObject#setAccessible(boolean) 的文档方法:

A value of false indicates that the reflected object should enforce Java language access checks.

因此,设置 false 值并不意味着该字段不可访问。它只是意味着将强制执行正常的 Java 访问规则。

因此,public 成员将像正常情况一样被访问。对于protected成员也是如此(它们可以在同一个包中访问,并且可以在其他包中访问子类)。

关于java - field.setAccessible(false) 对非私有(private)字段的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18621604/

相关文章:

java - 在 DAO 方法中访问延迟加载的集合时出现 NullPointerException

java - 通过成员注解获取外部类

c# - 检查 propertyInfo 是否实现了一个类

java - Java SE 7 何时发布?

java - 使用 Point2D 中的距离将变量与数组进行比较

选项的反射和类型检查

c# - 如何递归迭代实体的属性

c# - 关于 C# 表达式树的建议

java - PrimeFaces 4 的 taglib 定义在哪里?

java - Primefaces InputSwitch 组件在 Ajax 请求后复制