泛型和参数化构造函数
问题描述:
这是关于参数化方法的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
为<>
。在这种情况下,推断基于managers
:T[]=Manager[] => T=Manager
。
因此表达式产生一个BinaryTree<Manager>
,它不能被分配到BinaryTree<Person>
。
两种解决方法:
new BinaryTree<Person>(managers);
new BinaryTree((Person[])managers);
对于第一构造
<E extends T> BinaryTree(E[] items)
我们有两件事情,现在来推断,E
和T
,表达new BinaryTree<>(managers)
现在E=Manager
是推断;然而T
尚未推断。编译器然后查看目标类型Binary<Person>
,这有助于推断出T=Person
。
Java类型推断相当混乱。为什么程序员会关心我刚刚描述的内容?当有疑问时,教训是明确地提供类型参数。
在两个构造函数之间,我一定会选择BinaryTree(T[] items)
。 E
版本只是更复杂的没有好处(虽然它发生在这个特定的例子更好)
这一切都有道理,谢谢。所以我猜在使用 BinaryTree(E []项) –
2013-02-27 02:24:32
没有多大意义,因为'T []'arg可以接受任何'X []',其中''X''是'T'的子类型' 。注意这对'List'不起作用。如果我们想要接受任何'List',其中'X'是'T'的子类型,我们需要'List extends T>'作为arg类型。 –
irreputable
2013-02-27 02:28:30