Java通用类型不匹配错误

时间:2015-07-02 14:09:56

标签: java generics lambda java-8

我有一个带有构造函数签名的类,如下所示:

public class MyClass <U>{
    public <T> MyClass(Set<T> data, Function<T,U> func)...
}

没关系。但是我想重载构造函数,因为如果你不提供函数func,它只会使用(item)->{return item;}。我写了另一个看起来像这样的构造函数:

public <T> MyClass(Set<T> data){
    this(
      data,
      (item)->{return item;}
    );
}

这导致了类型不匹配错误,因为我作为构造函数的参数提供的函数采用类型T的值,并返回相同的值,该值应为U 。我不明白为什么代数类型系统没有看到在这种情况下U和T是相同的,那没关系?

3 个答案:

答案 0 :(得分:7)

系统必须假设T和U是两种不同的类型,因为你给它们两个不同的名字。但你可以从你的第二个ctor中删除其他泛型类型:

public class MyClass <U>{
    public <T> MyClass(Set<T> data, Function<T,U> func) {...}
    public MyClass(Set<U> data){
        this(
          data,
          (item)->{return item;}
        );
    }
}

答案 1 :(得分:3)

让我们尝试使用第二个构造函数创建一个类的实例:

Set<Integer> ints = new HashSet<>();
MyClass<String> myobj = new <Integer> MyClass (ints);

您的第一个构造函数需要Set<Integer>Function<Integer,String>个参数,但您的第二个构造函数会尝试将Function<Integer,Integer>传递给它。这就是你的代码没有通过编译的原因。

定义泛型类和方法时,它们必须对可替换其类型参数的任何类型组合有效。

答案 2 :(得分:0)

由于您声明了两种不同的类型T和U,编译器合理地认为它们是不同的。如果它们相同,请不要声明T并仅使用U:

public MyClass(Set<U> data){
    this(
      data,
      (item)->{return item;}
    );
}