inner classes mixed with method handles: does it matter?

John Rose john.r.rose at oracle.com
Fri Oct 22 03:34:32 PDT 2010


The JSR 292 EG is discussing access rules for method handles.

The draft spec. say that CONSTANT_MethodHandles in the constant pool, and dynamically looked up method handles, are accessible to related nested classes:

     * In general, the conditions under which a method handle may be
     * created for a method {@code M} are exactly as restrictive as the conditions
     * under which the lookup class could have compiled a call to {@code M}.
     * This rule is applied even if the Java compiler might have created
     * an wrapper method to access a private method of another class
     * in the same top-level declaration.
     * For example, a lookup object created for a nested class {@code C.D}
     * can access private members within other related classes such as
     * {@code C}, {@code C.D.E}, or {@code C.B}.

That is, method handle constants, and method handles obtained from dynamic member lookup, can access private members of other classes, if and only if those other classes are nest-mates of the requesting class.

It is as if the corresponding Core Reflection API object has its "accessible" bit set to true, if the requesting class and the target member's class are both under the same package member, as determined by repeated use of Class.getEnclosingClass, and subject to the JVM's consistency checks on that query.

Question for users:  If we were to drop this feature, and use the more limited access rules from reflection, would anybody miss it?  If you are generating code, you'll have to generate "access$" methods like javac, or just not use privates.  If you are reflecting, you'll have to do the setAccessible(true) dance.

In any case, you always have Lookup.unreflect(Method), and you can setAccessible on the Method to disable access checking.  The problem with setAccessible is that it requires privilege elevation.

Even if your language does not emit inner classes (very few do) this issue may affect it, if you are relying on access to non-public members of Java classes.  In this case, getting a method handle on a nested class member may be done with a Lookup object on its enclosing class (or any other nest-mate) in the draft design, but must be done with a Lookup object on the exact inner class, if we drop this feature.

Comments?

-- John


More information about the mlvm-dev mailing list