编译错误:Lambda目标类型交集类型

gud*_*dge 5 java eclipse lambda java-8

public class X {
  Object o = (I & J) () -> {};
}
interface I {
   public void foo(); 
}
interface J {
   public void foo();
   public void bar(); 
}
Run Code Online (Sandbox Code Playgroud)

Oracle编译器抛出错误:

 X.java:2: error: incompatible types: INT#1 is not a functional interface
  Object o = (I & J) () -> {};
                     ^
multiple non-overriding abstract methods found in interface INT#1
where INT#1 is an intersection type:
INT#1 extends Object,I,J
1 error
Run Code Online (Sandbox Code Playgroud)

Eclipse编译器编译得很好.

哪种实现看起来正确?

以上示例的修改形式:

public class X {
  Object o = (I & J) () -> {};
}
interface I {
   public void foo(); 
}
interface J {
   public void foo();
}
Run Code Online (Sandbox Code Playgroud)

Eclipse编译器抛出错误.Oracle编译器接受它.

我认为Oracle编译器是正确的.

考虑测试用例:

interface I {
  default void foo() { System.out.println("foo I \n"); }
  default void bar() { System.out.println("bar I \n"); }
}
interface J extends I {
   default void foo() { System.out.println("foo J \n"); }
 }
public class Y {
    public static void main(String argv[]) throws Exception {
        J j = new J() {
        };

        ((I & J) j).foo();
        ((I & J) j).bar();
    }
Run Code Online (Sandbox Code Playgroud)

}

Oracle和Eclipse Compiler的输出是:

foo J
bar I
Run Code Online (Sandbox Code Playgroud)

根据输出,我可以得出结论,Oracle看起来是正确的.

让我知道你们是如何解释它的.

谢谢

Bri*_*etz 2

在第一个示例中,I&J不是函数式接口(仅具有一个抽象非对象方法的接口)。所以javac报错是正确的。

在第二种情况下,I&J是一个函数式接口,因此 javac 又是正确的。

听起来像是 Eclipse 编译器中的两个错误。