Enum's values() method access level

Andremoniy :

JLS 8 states that each enum class has implicitly declared method:

public static E[] values();

So, it is public by specification.

At the same time Class.getEnumConstantsShared() method forcibly makes it accessible:

            final Method values = getMethod("values");
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction<Void>() {
                    public Void run() {
                            values.setAccessible(true);
                            return null;
                        }
                    });
            @SuppressWarnings("unchecked")
            T[] temporaryConstants = (T[])values.invoke(null);

I'm wondering: what's the sense?

k5_ :

Short answer: otherwise it would not work with anything but public Enums

To access the method MyEnum.values(), the method needs to be public (it always is) and MyEnum needs to be public (or it must be in the same package).

The method is accessed from the Class::getEnumConstantsShared() in the package java.lang. So as long as the none public Enum is not in java.lang getEnumConstantsShared() will not have access to it. Access is determined by the direct caller not by somebody higher up the call stack. The direct caller of values.invoke(null) is the code in java.lang.Class so the accessibility rules apply to exactly that context

That can be easily verified (following code will not work) if you create a static method in some package a

public class ValueGetter {
    public static Object[] getValues(Class<? extends Enum> enu) throws Exception {
        Method method = enu.getMethod("values");
        return (Object[]) method.invoke(null);
    }
}

And try to access it like this snippet in a different package b

public class EnumTest {
    enum MyEnum {
        LITERAL;
    }

    public static void main(String[] args) throws Exception {
        System.out.println(Arrays.toString(ValueGetter.getValues(MyEnum.class)));
    }
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=453624&siteId=1