Why is List<String> a subtype of List, but not of List<Object>?
Possible Duplicate:
Why is Listnot a sub-type of List
EDOCX1 0是Java中的EDOCX1×1的子类型吗?
那么,为什么我不能将
Isn't String a subtype of Object in Java?
是的,但这并不能使
考虑这个例子:
1 2 3 4 |
如果(假设)
I can, though, pass such an object into a function that accepts List as a parameter.
是的,那是真的。但接下来您要处理的是原始类型,当将对象从列表中拉出时,必须使用显式类型转换。例如,上述内容需要改写如下:
1 2 3 4 |
注意类型转换意味着我们必须用运行时类型安全替换静态类型安全。(当然,在这种情况下,类型转换将在运行时失败,因为实例的类型错误。)
您将参数化类型与具体类型混淆。
给定
EDOCX1 11是一个有界通配符参数化类型,它将允许您放置EDCOX1×12的任何东西,但是因为Java EDCOX1中的每一个类都有12个语义,它在语义上与前两个选项没有任何不同。
现在,它们的功能都是一样的,但它们将无法通过
换言之:
1 | public void myfunction(final List<Object> list) {} |
只接受
以下是示例:
1 2 | Collection<?> coll = new ArrayList<String>(); List<? extends Number> list = new ArrayList<Long>(); |
您不能实例化一个
Java中的泛型与C++中的实现不同,而不是混淆的名称。
在爪哇中,当EDCX1〔33〕是EDCX1〔1〕的亚型时,EDCX1〔31〕不是EDCX1〔0〕的亚型。此规则提供类型安全性。
假设我们允许一个
1 2 3 4 5 6 7 8 9 10 | public void foo(List<Object> objects) { objects.add(new Integer(42)); } List<String> strings = new ArrayList<String>(); strings.add("my string"); foo(strings); // this is not allow in java // now strings has a string and an integer! // what would happen if we do the following...?? String myString = strings.get(1); |
因此,强制这样做提供了类型安全性,但它也有一个缺点,即灵活性较低。请考虑以下示例:
1 2 3 4 5 | class MyCollection<T> { public void addAll(Collection<T> otherCollection) { ... } } |
这里有一个
为了解决这个问题,Java提供了他们称之为"通配符"的东西。通配符是一种提供协方差/反方差的方法。现在考虑使用通配符进行以下操作:
1 2 3 4 5 6 7 8 | class MyCollection<T> { // Now we allow all types S that are a subtype of T public void addAll(Collection<? extends T> otherCollection) { ... otherCollection.add(new S()); // ERROR! not allowed (Here S is a subtype of T) } } |
现在,对于通配符,我们允许在类型t中使用协方差,并阻止不安全类型的操作(例如,将项添加到集合中)。这样我们就获得了灵活性和类型安全性。
除了上面所说的,为了满足您的需要,您需要显式地将参数声明为