【问题标题】:strange type inferring behaviour奇怪的类型推断行为
【发布时间】:2016-02-29 11:29:58
【问题描述】:

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

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<>());
    } 
}

Test t = new Test(...);由于以下错误无法编译:

The constructor Test(int, (<no type> s) -> {}, new SubClass<>()) is undefined

现在我发现了两种不同的可能性来让这段代码正常工作:
1) 为功能接口参数设置显式类型

Test t = new Test(
    42,
    (String s)->{},
    new SubClass<>());

2) 或移除重载的构造函数。

/* public <T> Test(T obj, SubClass<T>...sc){} */

我真的不明白这里的编译器问题以及为什么我的解决方案有效。有人可以解释一下这里发生了什么。

【问题讨论】:

  • 用 1.8.0_65 编译对我来说很好。你是用哪个 javac 版本编译的?
  • 使用了 1.8.0_45 刚刚更新到 1.8.0_65 但还是一样的错误。
  • 确定一下,您使用的是 Eclipse 吗?
  • 是的,我使用的是 Eclipse 4.4.0,只是从命令行中注意到它可以工作。这似乎是一个日食问题。
  • 是的,Eclipse 有自己的编译器,它与 Java 8 的新特性有很多问题。尝试查看是否还没有发布类似的错误。如果没有,您可以将其报告给开发团队。就个人而言,我改用了 IntelliJ,我认为这将是确定的。

标签: java generics lambda constructor-overloading inferred-type


【解决方案1】:

这肯定是 Eclipse 内部使用的 Eclipse Compiler for Java (ECJ) 的问题。要解决它,请将参数类型添加到 lambda:

public static void main(String[] args){
    Test t = new Test(
                42,
                (String s)->{},
                new SubClass<>());
} 

这样它编译得很好(至少在 Eclipse Luna 4.4.2 中)。

【讨论】:

  • 与 IntelliJ 和命令行一起使用。正确的Java。坏坏的日食。感谢您的帮助
猜你喜欢
  • 2020-08-12
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-29
相关资源
最近更新 更多