-
Bug
-
Resolution: Fixed
-
P2
-
8
-
b119
-
Verified
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;
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;
- relates to
-
JDK-8028129 Type checking: signature polymorphic MethodHandle.invoke(Object[])
-
- Closed
-
-
JDK-8028690 Lambda Spec: Clarify how parameter/return types are derived for MethodHandle::invoke
-
- Closed
-
-
JDK-8203488 Remove error generation from TransTypes
-
- Resolved
-