EquilateralTriangle
是Triangle
的子类型。
List<? super EquilateralTriangle> equilateralTriangle =
new ArrayList<Triangle>(Arrays.asList(new Triangle(), new Triangle()));
equilateralTriangle.add(new Triangle()); // doesn't work
equilateralTriangle.add(new EquilateralTriangle()); // works
据我所知List<? super EquilateralTriangle>
是声明,new ArrayList<Triangle>
我们告诉编译器我的arraylist是三角形类型的具体内容。那为什么编译器会在第二行抱怨?我插入了与实例化arraylist时定义的类型参数中定义的相同的值。
Java arraylist定义说:
class ArrayList<E> extends AbstractList<E>
public ArrayList(Collection<? extends E> c)
和boolean add(E e);
ArrayList
。
因此,类型E
可以被称为Triangle
。然后add
一定不要抱怨,因为我在Triangle
构造函数中传递了ArrayList
。我理解中缺少什么?
答案 0 :(得分:1)
看看以下陈述。显然,添加 String 可以正常工作,而添加 Object 会导致编译时错误。
List<String> items = ...;
items.add(new String()); // works
items.add(new Object()); // error
现在,让我们在您的问题中使用通配符:
List<? super String> items = ...;
在此变量声明中,?
代表未知类型,即 String 或 String 。该类型未推断/推断。它只是一个未知类型。编译器必须假设? super String
可以是String
。正如我们上面所看到的,您不应该将 Objects 添加到 Strings 列表中。
答案 1 :(得分:0)
nosid's answer解释了逆变部分。我只是解决这个问题:
为什么编译器会在第二行抱怨?我插入了与实例化arraylist时定义的类型参数中定义的相同的值。
我可以问你关于这段代码的同样问题:
Object object = new ArrayList<Triangle>();
object.add(new Triangle());
为什么这不起作用?编译器不知道object
是ArrayList<Triangle>
吗?
答案是否定的。编译器对实例化的类型并不重要。重要的是您调用add
的变量类型。