简体   繁体   中英

field.setAccessible(false) effect on NON-private fields

What effect has field.setAccessible(false) on non-private fields?

I expected that the access to this member is denied, but that's not the case!

I tried to dig in the source-code, but at some point ( Field#getFieldAccessor(Object) ) i lost track of what is happening.

I created a special class for this situation:

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

}

And created a Demo:

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

        }

    }

}

Output:

'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

As per the documentation of AccessibleObject#setAccessible(boolean) method:

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

So, setting a false value doesn't mean that the field won't be accessible. It just means that the normal Java access rules will be enforced.

So, public members will be accessed as it is done normally. Same for protected members (They will be accessible in same package, and subclass in other package).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM