MethodHandle::invoke または MethodHandle::invokeExact を、MethodHandle を受け入れて生成された出力を返す関数インターフェイスのメソッド参照として使用できるかどうかを確認しようとしていました。
(invoke と invokeExact はシグネチャ ポリモーフィックであるため、InvokeExact でのメタファクトリ呼び出しであることはわかっています。ただし、invoke/invokeExact の適切なバージョンを派生させるために必要だった作業をコンパイラが省略できるかどうかを知りたかったのです。)
呼び出す.InvokeExact0
package invoke;
import java.lang.invoke.MethodHandle;
import static java.lang.System.out;
import static java.lang.invoke.LambdaMetafactory.metafactory;
import static java.lang.invoke.MethodHandles.lookup;
import static java.lang.invoke.MethodType.methodType;
@FunctionalInterface
public interface InvokeExact0<OUTPUT> {
public OUTPUT invokeExact(MethodHandle methodHandle) throws Throwable;
public static <OUTPUT> InvokeExact0<OUTPUT> new_(InvokeExact0<OUTPUT> invokeExact) {
return invokeExact;
}
public static void main(String... arguments) throws Throwable {
out.println(
(InvokeExact0<String>) metafactory(
lookup(),
"invokeExact",
methodType(InvokeExact0.class),
methodType(
Object.class,
MethodHandle.class
),
lookup().findVirtual(
MethodHandle.class,
"invokeExact",
methodType(String.class)
),
methodType(
String.class,
MethodHandle.class
)
)
.getTarget()
.invokeExact()
);
out.println(InvokeExact0.new_(MethodHandle::invokeExact));
}
}
結果
invoke.InvokeExact0$$Lambda$1/1878246837@5ca881b5
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:328)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:296)
at invoke.InvokeExact0.main(InvokeExact0.java:41)
Caused by: java.lang.invoke.LambdaConversionException: Incorrect number of parameters for instance method invokeVirtual java.lang.invoke.MethodHandle.invokeExact:(MethodH
andle)Object; 0 captured parameters, 1 functional interface method parameters, 1 implementation parameters
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:193)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:289)
... 2 more
良いニュースは、メタファクトリ アプローチが機能する機能インターフェイス インスタンスを合成できたことです (印刷されているように: invoke.InvokeExact0$$Lambda$1/1878246837@1be6f5c3 )。悪いニュースは、メソッド参照アプローチが LambdaConversionException を引き起こし、それがさらに BootstrapMethodError を引き起こしたことです。
とにかくメタファクトリの回避策が存在するため、LambdaConversionException のエラーの詳細をどのように解釈することになっているのかを尋ねたいと思います。