我正在玩Java 8 lambdas,方法引用和接口默认方法来探索currying的精彩世界,然后我得到了这个Java错误我无法理解.
这是代码:
public class Main {
public interface CurryBiConsumer<T, U> extends BiConsumer<T, U> {
default public CurryConsumer<U> curryFirst(T t) {
return (u) -> accept(t, u);
}
default public CurryConsumer<T> currySecond(U u) {
return (t) -> accept(t, u);
}
}
public interface CurryConsumer<T> extends Consumer<T> {
default public Runnable curry(T t) {
return () -> accept(t);
}
}
static void execute(Runnable r) {
System.out.println("BEFORE");
r.run();
System.out.println("AFTER");
}
static void display(String str, int count) {
System.out.println("DISP: " + str + " " + count);
}
public static void main(String[] args) {
CurryBiConsumer<String, Integer> bc = Main::display;
execute(bc.curryFirst("Salomon").curry(42));
}
}
Run Code Online (Sandbox Code Playgroud)
Eclipse没有给我任何错误但是当我运行它时,我得到了这个运行时错误:
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 com.test8.Main.main(Main.java:34)
Caused by: java.lang.ClassFormatError: Duplicate method name&signature in class file com/test8/Main$$Lambda$1
at sun.misc.Unsafe.defineAnonymousClass(Native Method)
at java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass(InnerClassLambdaMetafactory.java:324)
at java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:194)
at java.lang.invoke.LambdaMetafactory.altMetafactory(LambdaMetafactory.java:473)
at java.lang.invoke.CallSite.makeSite(CallSite.java:301)
... 2 more
Run Code Online (Sandbox Code Playgroud)
有人可以解释这是什么错误,它为什么会发生以及如何绕过它?
谢谢 :)
Mar*_*nik 13
将system属性设置jdk.internal.lambda.dumpProxyClasses为指向文件系统上的目录.您将获得com/test8/Main$$Lambda$1转储到该位置的合成匿名类的字节码.打开该类文件,javap看看发生了什么.你应该在那里找到两个相同方法的声明.
javap当使用Eclipse编译时,这是上述过程产生的输出:
final class test.Main$$Lambda$1 implements test.Main$CurryBiConsumer {
public void accept(java.lang.Object, java.lang.Object);
Code:
0: aload_1
1: checkcast #14 // class java/lang/String
4: aload_2
5: checkcast #16 // class java/lang/Integer
8: invokestatic #22 // Method test/Main.lambda$0:(Ljava/lang/String;Ljava/lang/Integer;)V
11: return
public void accept(java.lang.Object, java.lang.Object);
Code:
0: aload_1
1: checkcast #14 // class java/lang/String
4: aload_2
5: checkcast #16 // class java/lang/Integer
8: invokestatic #22 // Method test/Main.lambda$0:(Ljava/lang/String;Ljava/lang/Integer;)V
11: return
}
它应该如何,以及它是什么javac:
final class test.Main$$Lambda$1 implements test.Main$CurryBiConsumer {
public void accept(java.lang.Object, java.lang.Object);
Code:
0: aload_1
1: checkcast #14 // class java/lang/String
4: aload_2
5: checkcast #16 // class java/lang/Integer
8: invokevirtual #20 // Method java/lang/Integer.intValue:()I
11: invokestatic #26 // Method test/Main.display:(Ljava/lang/String;I)V
14: return
}
结论:这是Eclipse JDT编译器的一个问题.有人应该报告:)
从Eclipse Luna开始,这个bug已得到修复.
| 归档时间: |
|
| 查看次数: |
4686 次 |
| 最近记录: |