2013-02-27 2 views
1

Это расширение этого previous question о параметризованных методах. Я читаю ту же книгу. После того, как пример в предыдущем вопросе, автор улучшает классGenerics and Parameterized Constructors

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 в моем конструкторе?

ответ

2

Для 2-го конструктора, когда компилятор видит

new BinaryTree<>(managers) 

он должен сделать вывод T для <>. В этом случае вывод основан на managers: T[]=Manager[] => T=Manager.

Следовательно, выражение дает значение BinaryTree<Manager>, которое не может быть присвоено BinaryTree<Person>.

Два обходные пути:

new BinaryTree<Person>(managers); 

new BinaryTree((Person[])managers); 

Для 1-го конструктора

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

у нас есть две вещи, чтобы вывести сейчас, E и T, в выражении new BinaryTree<>(managers)

Теперь E=Manager является вывод; однако T еще не выведен. Затем компилятор просматривает целевой тип Binary<Person>, что помогает сделать вывод, что T=Person.


Вывод типа Java довольно грязный. Почему любой программист должен узнать, что я только что описал? Урок, если у вас есть сомнения, аргументы типа поставки явно.

Между двумя конструкторами я бы выбрал BinaryTree(T[] items). Версия E просто сложна без каких-либо преимуществ (хотя для этого конкретного примера лучше работать)

+0

Все это имеет смысл, спасибо. Поэтому я думаю, что нет смысла использовать BinaryTree (E [] items) –

+0

Нет смысла, так как 'T []' arg будет принимать любые 'X []' где 'X' является подтипом' T' , Обратите внимание, что это не будет работать для 'List'. Если мы хотим принять любой 'List ', где 'X' является подтипом' T', нам нужен 'List ' как тип arg. – irreputable