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