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@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to