Sim*_*imo 2 java generics wildcard readonly diamond-operator
考虑以下代码(代码中有两个问题):
import java.util.*;
public class Tree<T> {
private T info;
private List<Tree<? extends T>> children = new ArrayList<Tree<? extends T>>();
public Tree<? extends T> getChildren(int n) {
return children.get(n);
}
public void addChildren(Tree<? extends T> children) {
this.children.add(children);
}
public static void main(String[] args) {
Tree<?> b2; // so b2 is a reference of a Tree of unknown type
b2 = new Tree<Number>(); /* to allow b2 to call addChildren() with Tree<? extends Number> aguments */
b2.addChildren(new Tree<Number>()); // 1) why it doesn't work ?
b2.addChildren(new Tree<Integer>()); // neither does this one!
b2.addChildren(new Tree<>()); // 2) but with diamond <> it works ?
}
}
Run Code Online (Sandbox Code Playgroud)
b2.addChildren(new Tree<Number>())?b2.addChildren(new Tree<>()).编译器在菱形<>中使用哪种类型列表?问题是你已声明b2有一种类型Tree<?>.
如果您将main方法重写为两种方法,问题会更清晰:
public static void main(String[] args) {
test(new Tree<Number>());
}
private static void test(Tree<?> b2) {
// "<?>" means we don't know what the generic type of b2 is, so
// the compiler can't possibly know if it's safe to add any type
// of children...
b2.addChildren(new Tree<Number>()); // 1) why it doesn't work ?
b2.addChildren(new Tree<Integer>()); // neither does this one!
b2.addChildren(new Tree<>()); // 2) but with diamond <> it works ?
}
Run Code Online (Sandbox Code Playgroud)
即使您创建了一个new Tree<Number>(),您也会立即丢弃该信息.你的代码只记得b2包含一些未知类型的树,因为它Tree<?>意味着"某种类型的树,但我不知道什么类型."
由于我们不知道树的类型是什么,我们如何知道它是否可以安全地呼叫addChildren(new Tree<Number>()),new Tree<Integer>()或者new Tree<String>()或者new Tree<JTable>()?编译器不知道.你可能还记得你放在那里的东西,但是那种类型b2不带有那些信息,所以编译器没有任何方法可以知道.