MethodHandle accessing private method of outer class

Jochen Theodorou blackdrag at gmx.org
Sun Apr 1 12:37:19 UTC 2018


On 01.04.2018 05:00, David Holmes wrote:
> 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+).

I tried that with 9.0.4, and no, there is no subtype relationship.

>> 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.

seems it is not for the invocation... but at least for the lookup object 
this seems to be, which helps a lot already

>>> 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.

ok, got it. Thx

bye Jochen


More information about the mlvm-dev mailing list