Java 奇异型推断行为

Java 奇异型推断行为,java,generics,lambda,constructor-overloading,inferred-type,Java,Generics,Lambda,Constructor Overloading,Inferred Type,我有一个非常复杂的类,它获取一个泛型值、一个函数接口和一些泛型类型的子类。现在我注意到一些与类型推断有关的奇怪行为。请查看以下代码: public class Test{ public static class SubClass<F>{ public SubClass(){} } @FunctionalInterface public interface FuncInterface { void operation(S

我有一个非常复杂的类,它获取一个泛型值、一个函数接口和一些泛型类型的子类。现在我注意到一些与类型推断有关的奇怪行为。请查看以下代码:

public class Test{
    public static class SubClass<F>{
        public SubClass(){}
    }

    @FunctionalInterface
    public interface FuncInterface {
        void operation(String s);
    }

    @SafeVarargs
    public <T> Test(T obj, FuncInterface fi, SubClass<T>...sc){}

    @SafeVarargs
    public <T> Test(T obj, SubClass<T>...sc){}

    public static void main(String[] args){
        Test t = new Test(
                    42,
                    (s)->{},
                    new SubClass<>());
    } 
}
公共类测试{
公共静态类子类{
公共子类(){}
}
@功能接口
公共接口{
无效操作(字符串s);
}
@安全变量
公共测试(tobj,funcfi,子类…sc){}
@安全变量
公共测试(T obj,子类…sc){}
公共静态void main(字符串[]args){
测试t=新测试(
42,
(s) ->{},
新的子类());
} 
}
直线测试t=新测试(…);由于以下错误,无法编译:

The constructor Test(int, (<no type> s) -> {}, new SubClass<>()) is undefined
构造函数测试(int,(s)->{},new SubClass())未定义
现在我发现了两种不同的方法来让代码正常工作:
1) 为函数接口参数设置显式类型

Test t = new Test(
    42,
    (String s)->{},
    new SubClass<>());
Test t=新测试(
42,
(字符串s)->{},
新的子类());
2) 或者删除重载的构造函数

/* public <T> Test(T obj, SubClass<T>...sc){} */
/*公共测试(T obj,子类…sc){*/

我真的不明白编译器的问题,也不明白为什么我的解决方案能工作。谁能解释一下这里发生了什么。

这肯定是Eclipse内部使用的Eclipse Java编译器(ECJ)的问题。要解决此问题,请向lambda添加参数类型:

public static void main(String[] args){
    Test t = new Test(
                42,
                (String s)->{},
                new SubClass<>());
} 
publicstaticvoidmain(字符串[]args){
测试t=新测试(
42,
(字符串s)->{},
新的子类());
} 

通过这种方式,它编译得很好(至少在EclipseLuna 4.4.2中是这样)。

使用1.8.0@为我编译得很好。您使用哪个javac版本编译?使用了1.8.0_45,刚刚更新到1.8.0_65,但仍然是相同的错误。请确定,您使用的是Eclipse吗?是的,我使用的是Eclipse 4.4.0,刚刚从命令行注意到它可以工作。这似乎是eclipse的问题。是的,eclipse有自己的编译器,它在新的Java8特性方面有很多问题。尝试查看是否已经发布了类似的错误。如果没有,您可以向开发团队报告。就我个人而言,我切换到IntelliJ,我认为这将是确定的。与IntelliJ和命令行一起使用。正确的Java。糟糕的日食。谢谢你的帮助