MethodHandle accessing private method of outer class

David Holmes david.holmes at oracle.com
Sun Apr 1 03:00:17 UTC 2018


On 1/04/2018 11:13 AM, Jochen Theodorou wrote:
> On 01.04.2018 01:51, David Holmes wrote:
> [...
> Anonymous inner class able to call private method in enclosing class 
> directly using method handles and no helper methods
> ...]
>> But MethodHandles went to a lot of trouble to allow the same accesses 
>> as the language permits (though sometimes needing to use special 
>> mechanisms like Lookup.in). 
> 
> What really surprised me was that I was able to use the anonymous inner 
> class as receiver for the handle I created from the surrounding class 
> and still got a successful call. Sure, when I think about an unqualified 

You should not be able to call a method of the enclosing class on an 
instance of the inner class (unless there is also a subtype relationship 
there). But there have been some oversights in that area which have been 
fixed more recently (8u131, 9+).

> method call in an inner class being able to call to an outer class 
> method, then this kind of behaviour makes sense. But having had to do 
> with Reflection before and knowing the bytecode side and what javac 
> usually generates I was really surprised about this. Ok, I was actually 
> already surprised about the lookup object of the inner class allowing me 
> to findSpecial that private method of the outer class, but that I 
> explained already. I am only not sure if this still qualifies as "same 
> accesses as the language permits". Maybe I am overthinking here, because 
> I always have trouble to look at code without seeing it from the 
> perspective of the compiler. And for the java compiler it is more a 
> question about choosing the right receiver, which it can do at compile 
> time. Thus it seems not to be necessary to have this. With Java9 
> qualifying a lot of things I did do normally as a "you should not do 
> this and we actively prevent you from doing this now" I got a bit more 
> careful with unexpected features.
> 
>> I can't say for sure MH has "always" allowed this (sometimes the 
>> implementation has lagged when it comes to private method access, 
>> particularly when private interface methods were introduced) - though 
>> it would be easy to check.
> 
> If this is the expected behaviour for a current JDK8 and newer I am fine.
> 
>> Going forward, for JDK 11 we expect JEP 181 "Nestmates" to be in 
>> place, which implements the language access semantics consistently 
>> across the VM, MH and core reflection. So yes a nested type has full 
>> access to its enclosing types, and full access to all other nested 
>> types in the same nest (ie all types directly or indirectly nested in 
>> a given top-level class).
> 
> which means in the future I can do something like this in an inner class?
> 
> enclosingClass.getDeclaredMethod("somePrivateMethod").invoke(innerClassInstance)? 
> 
> 
> right now I would have to use setAccessible and the enclosing class 
> instance to make this work.

You won't need to use setAccessible. But the receiver must still be an 
instance of the class whose method you are invoking.

David

> 
> bye Jochen
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


More information about the mlvm-dev mailing list