how can I write Java 1.7 code for a Java 1.6 compiler, where the diamond can not be used?
Example:
private ReplacableTree<E> convertToIntended(Tree<? extends E> from,ReplacableTree<E> to) {
TreeIterator<? extends E> it = new TreeIterator<>(from.getRoot());
while(it.hasNext()) {
E e = it.next().getElem();
to.add(e);
}
return to;
}
public class TreeIterator<E> implements TreeIter<Node<E>> {
....
}
It is not allowed to write…
TreeIterator<? extends E> it = new TreeIterator<?>(from.getRoot());
TreeIterator<? extends E> it = new TreeIterator<E>(from.getRoot());
TreeIterator<? extends E> it = new TreeIterator<? extends E>(from.getRoot());
Especially the third one is confusing for me. Why doesn’t it work? I just want to read Elements from a Tree (which could be a subtype tree), and when puch each of it in a new Tree with Elements of type E.
Wildcard types are not permitted as type arguments in class instance creation expressions:
so the first and third variants are not valid.
Variant 2 is invalid because the
TreeIterator<E>constructor wants aNode<E>, but you give it aNode<? extends E>.As for the solution, Java 5 and 6 did not have type inference for constructors, but do have type inference for methods, and in particular capture conversion. The following ought to compile:
where
Edit: You asked in the comment:
Being a wildcard type, the type
Node<? extends E>represents a family of types.Node<capture#2-of ? extends E>refers to a specific type in that family. That distinction is irrelevant in this case. What matters is thatNode<? extends E>is not a subtype ofNode<E>, and hence you can’t pass an instance ofNode<? extends E>to a constructor expecting aNode<E>.