JDK 20 |
---|
20 b25Fixed |
CSR :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
public class InterfaceMethodref { interface I { void m(); } abstract class C implements I {} public void test(C arg) { Runnable r = arg::m; } } The method reference 'arg::m' compiles to: 6: invokedynamic #3, 0 // InvokeDynamic #0:run:(LInterfaceMethodref$C;)Ljava/lang/Runnable; With bootstrap method: 0: #22 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: #23 ()V #24 invokeinterface InterfaceMethodref$I.m:()V #23 ()V Note that the metafactory call's implMethod is "invokeinterface InterfaceMethodref$I.m:()V", not "invokevirtual InterfaceMethodref$C.m:()V". This is incorrect: the compiler must refer to the type of the receiver, not the type of the declaring class/interface, per JLS 13.1 (see "the qualifying type of the method invocation"). Also, FWIW, this combination of implMethod and invokedType violates the invariants claimed to be enforced by LambdaMetafactory (specifically, referring to the Javadoc, D1 != A1). Apparently this isn't currently enforced.
|