As far as I can tell, with the introduction of MethodHandle in Java 7 came the introduction of compiler-generated method overloads.
The javadoc for MethodHandle states (I've trimmed the examples):
Here are some examples of usage:
Object x, y; String s; int i; mh = ... // (Ljava/lang/String;CC)Ljava/lang/String; // (String, char, char) -> String s = (String) mh.invokeExact("daddy",'d','n'); // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; // (Object, Object, Object) -> Object x = mh.invokeExact((Object)1, (Object)2, (Object)3); // (Ljava/util/List;)I // (List) -> int i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3)); // (Ljava/io/PrintStream;Ljava/lang/String;)V // (PrintStream, String) -> void mh.invokeExact(System.out, "Hello, world.");
Each of the above calls generates a single invokevirtual instruction with the name invoke and the type descriptors indicated in the comments. The argument types are taken directly from the actual arguments, while the return type is taken from the cast immediately applied to the call. This cast may be to a primitive. If it is missing, the type defaults to Object if the call occurs in a context which uses the return value. If the call occurs as a statement, a cast is impossible, and there is no return type; the call is void.
In effect, invokeExact and friends behave as if there is an overload for every possible combination of paramaters and return type.
I've heard that MethodHandles are preparing for features in Java 8 like lambdas. (I know they are already useful for scripting languages.)
[/introduction]
So, are there more of these compiler-generated overloads hiding around in Java? Are there hints there will be more of them in the future (say, with extension methods)? Why is it necessary in the first place? Merely speed? How does it help lambdas out (I thought lambdas would compile to an anonymous inner class)?
In short, what's the rationale; why are they (generated overloads) useful now and in the future?
UPDATE: What I call compiler-generated overloads here, the Oracle guys call signature polymophic.
I just came across an Hotspot internals wiki on MethodHandles and invokedynamic
It makes a few interesting points that answer these questions (and a few more).
MethodHandle.invokeExact
and friends are unique, being the only signature polymorphic methods.invokevirtual
bytecode for MethodHandle.invoke* is secretly converted to an invokehandle
instruction.
invokehandle
is like invokedynamic
; a few internals are different, and where each invokedynamic
instruction must point to it's own Constant Pool Cache Entry (CPCE), invokehandle
s can share CPCEs.invokedynamic
uses the non-public MethodHandle.invokeBasic
on the HotSpot VM
MethodHandle.invokeBasic
is like invokeExact but more loose; for one it does not check the types of at the call-site with those of the callee.invokedynamic
) can be JIT-compiled
Additionally, lambda expressions will be implemented via invokedynamic
. (Got that from Edwin Dalorzo's answer.) This means lambda expressions
MethodHandle.invokeBasic
on the HotSpot VM (see above), andIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With