泛型和参数化构造函数

时间:2013-02-27 02:05:59

标签: java

这是关于参数化方法的previous question的扩展。我正在读同一本书。在上一个问题的例子之后,作者改进了

BinaryTree<T extends Comparable<? super T>>

通过添加以下构造函数

再次(并且他真的这么做)
public  <E extends T> BinaryTree(E[] items) {
    for(E item : items) {
        add(item);
}

根据上一个问题的精神,我尝试了这个构造函数:

public BinaryTree(T[] items) {
    for(T item : items) {
        add(item);
    }
}

并且示例代码无法使用我的构造函数进行编译:

public static void main(String[] args) {
    Manager[] managers = { new Manager("Jane", 1), new Manager("Joe", 3), new Manager("Freda", 3), new Manager("Bert", 2), new Manager("Ann", 2), new Manager("Dave", 2) };
    BinaryTree<Person> people = new BinaryTree<>(managers);
}

在上一个问题中更改add()方法和更改此构造函数之间有什么区别?为什么我不能在构造函数中传递T的子类型?

1 个答案:

答案 0 :(得分:2)

对于第二个构造函数,当编译器看到

new BinaryTree<>(managers)

需要为T推断<>。在这种情况下,推断基于managersT[]=Manager[] => T=Manager

因此,表达式产生BinaryTree<Manager>,无法将其分配给BinaryTree<Person>

两个解决方法:

new BinaryTree<Person>(managers);

new BinaryTree((Person[])managers);

对于第一个构造函数

<E extends T> BinaryTree(E[] items)

我们现在有两件事要推断,ET,在表达式new BinaryTree<>(managers)

现在推断E=Manager;但是,T尚未推断。然后编译器查看目标类型Binary<Person>,这有助于推断T=Person


Java类型推断非常混乱。为什么任何程序员都会关心我刚刚描述的内容?当有疑问时,教训是明确提供类型参数。

在两个构造函数之间,我肯定会选择BinaryTree(T[] items)E版本只是更复杂而没有任何好处(虽然它恰好对这个特定的例子更有效)