Relates :
|
|
Relates :
|
|
Relates :
|
Invocations of signature polymorphic methods (MethodHandle.invoke, MethodHandle.invokeExact) derive the bytecode descriptor of the method call from the call site rather than the method's declared signature ("([Ljava/lang/Object;)Ljava/lang/Object;"). See JLS 15.12.3. A method handle like MethodHandle::invoke or mh::invoke should do the same. But currently, the descriptor generated by javac always seems to be "([Ljava/lang/Object;)Ljava/lang/Object;". Test case: --- import java.lang.invoke.*; public class MHInvoke { interface TriFunction { Object apply(String a, char b, char c) throws Throwable; } public static void main(String... args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(String.class, char.class, char.class); MethodHandle ms = lookup.findVirtual(String.class, "replace", mt); System.out.println("result 1: " + ms.invoke("some string to search", 's', 'o')); TriFunction f1 = (a, b, c) -> ms.invoke(a,b,c); System.out.println("result 2: " + f1.apply("some string to search", 's', 'o')); TriFunction f2 = ms::invoke; System.out.println("result 3: " + f2.apply("some string to search", 's', 'o')); } } --- Expected: Run successfully Actual: BootstrapMethodError --- Looking at the bytecode, here's the 'invoke' call from the lambda body: 4: invokevirtual #15 // Method java/lang/invoke/MethodHandle.invoke:(Ljava/lang/String;CC)Ljava/lang/Object; And here's the 'invoke' call for the method reference (passed as an argument to 'metafactory' in the form of a MethodHandle): #74 invokevirtual java/lang/invoke/MethodHandle.invoke:([Ljava/lang/Object;)Ljava/lang/Object; This should look like the following instead: #74 invokevirtual java/lang/invoke/MethodHandle.invoke:(Ljava/lang/String;CC)Ljava/lang/Object;
|