泛型和参数化构造函数

泛型和参数化构造函数

问题描述:

这是关于参数化方法的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的子类型?

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

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版本只是更复杂的没有好处(虽然它发生在这个特定的例子更好)

+0

这一切都有道理,谢谢。所以我猜在使用 BinaryTree(E []项) – 2013-02-27 02:24:32

+0

没有多大意义,因为'T []'arg可以接受任何'X []',其中''X''是'T'的子类型' 。注意这对'List'不起作用。如果我们想要接受任何'List ',其中'X'是'T'的子类型,我们需要'List extends T>'作为arg类型。 – irreputable 2013-02-27 02:28:30