gpt4 book ai didi

Java 8 : Duplicate method name&signature lambda

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:54:11 24 4
gpt4 key购买 nike

我正在使用 Java 8 lambda、方法引用和接口(interface)默认方法来探索柯里化(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));
}
}

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

谁能解释这是什么错误,为什么会发生以及如何解决?

谢谢:)

最佳答案

将系统属性 jdk.internal.lambda.dumpProxyClasses 设置为指向文件系统上的目录。您将获得转储到该位置的合成匿名类 com/test8/Main$$Lambda$1 的字节码。用 javap 打开那个类文件,看看发生了什么。您应该在那里找到相同方法的两个声明。

更新

这是使用 Eclipse 编译时上述过程产生的 javap 输出:

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 开始,此错误已得到修复。

关于Java 8 : Duplicate method name&signature lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22686586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com