JDK是Oracle的JDK 1.8u65,但“低至” 1.8u25也曾出现该问题。
这是完整的SSCCE:
public final class Foo
{
private interface X
{
default void x()
{
}
}
private enum E1
implements X
{
INSTANCE,
;
}
private enum E2
implements X
{
INSTANCE,
;
}
public static void main(final String... args)
{
Stream.of(E1.INSTANCE, E2.INSTANCE).forEach(X::x);
}
}
这段代码会编译;但在运行时失败:
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
at com.github.fge.grappa.debugger.main.Foo.main(Foo.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Enum; not a subtype of implementation type interface com.github.fge.grappa.debugger.main.Foo$X
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
... 8 more
用代码修复它很容易。在主要方法中,您只需要:
// Note the
Stream.of(E1.INSTANCE, E2.INSTANCE).forEach(X::x);
编辑 实际上,还有第二种方法,如公认的答案中所述…用lambda替换方法引用:
Stream.of(E1.INSTANCE, E2.INSTANCE).forEach(x -> x.x());
嗯 发生什么事了?为什么首先要编译初始代码?我本来希望编译器注意到方法引用不是在任何东西Enum>上X,而是在上,但是没有…
我想念什么?这是编译器中的错误吗?对我的误解?