Reputation: 9784
This is an extension of this previous question about parameterized methods. I am reading the same book. After the example in the previous question, the author improves the
BinaryTree<T extends Comparable<? super T>>
class yet again (and he really does this time around) by adding the following constructor
public <E extends T> BinaryTree(E[] items) {
for(E item : items) {
add(item);
}
In the spirit of the previous question I tried this constructor instead:
public BinaryTree(T[] items) {
for(T item : items) {
add(item);
}
}
and the example code does not compile with my constructor:
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);
}
What is this difference between changing the add() method in the previous question and changing this constructor? Why can't I pass a subtype of T in my constructor?
Upvotes: 1
Views: 129
Reputation: 45433
For the 2nd constructor, when compiler sees
new BinaryTree<>(managers)
it needs to infer T
for the <>
. In this case, inference is based on managers
: T[]=Manager[] => T=Manager
.
Therefore the expression yields a BinaryTree<Manager>
, which cannot be assigned to BinaryTree<Person>
.
Two workarounds:
new BinaryTree<Person>(managers);
new BinaryTree((Person[])managers);
For the 1st constructor
<E extends T> BinaryTree(E[] items)
we have two things to infer now, E
and T
, in expression new BinaryTree<>(managers)
Now E=Manager
is inferred; however T
is not inferred yet. The compiler then looks at the target type Binary<Person>
, which helps to infer that T=Person
.
Java type inference is quite messy. Why would any programmer care to learn what I have just described? The lesson is, when in doubt, supply type arguments explicitly.
Between the two constructors, I would definitely choose BinaryTree(T[] items)
. The E
version is just more complexity without benefits (though it happens to work better for this particular example)
Upvotes: 2