我无法将我的知识与下面的示例程序联系起来。请参阅以下示例程序,然后我的怀疑低于该程序。
import java.util.*;
class A { }
class B extends A { }
class C extends B { }
public class sampleprog {
public static void main(String[] args) {
List<? super A> list1 = new ArrayList<A>();
list1.add(new A());//valid. ok
list1.add(new B());//valid, why? it is not super to A?
list1.add(new C());//valid, why? it is not super to A?
List<? super B> list2 = new ArrayList<A>();
list2.add(new A());//not valid. why? it is also super to B!!!
list2.add(new B());
list2.add(new C());
List<? super C> list3 = new ArrayList<C>();
list3.add(new A());//not valid, why? It is super to A so should be valid!!!
list3.add(new B());//not valid, why? It is super to A so should be valid!!!
list3.add(new C());
}
}
我的怀疑:
- 据我所知? super T
表示你可以添加的任何类都超级T
,但这里的输出是不同的?甚至子类也成功添加,这完全令人困惑。
- 输出与列表初始化(List<? super C> list3 = new ArrayList<C>();
)没有区别。在此初始化中,我分配了A
或B
的列表,输出相同!
请清除我的怀疑。
答案 0 :(得分:1)
如果我们在泛型声明中使用? super
,则引用可以指向相同的泛型类型的集合或超级泛型类型的集合。因此,在这种情况下,通过IS-A测试的所有内容都是有效的。
答案 1 :(得分:1)
List<? super B>
表示
List<? super B> list1 = new ArrayList<A>();
List<? super B> list1 = new ArrayList<B>();
是允许的。 ArrayList<A>
超级ArrayList<B>
,不是吗?我们可以将B
和C
添加到ArrayList<A>
和ArrayList<B
&gt;?我们可以。我们可以添加A
吗?仅限ArrayList<A>.
但List<? super B>
也允许指向ArrayList<B>
。因此,我们无法将A
添加到List<? super B>
。
答案 2 :(得分:1)
“?super T”表示您可以添加的任何类,必须是T或其子类的实例。
因此,list3中的List<? super C> list3 = new ArrayList<C>();
可以添加C类实例或其子类实例(SomeClass extends C
)。
父对象列表可以有自己的子对象,子对象,但是为子类创建的List不能有其父对象。希望你现在清楚。
答案 3 :(得分:0)
投票@ us2012的评论。
List<? super A>
类型为A. A,B和C A的所有子类型,因此可以添加它们。
List<? super B>
类型可以是A,B。B和C都是A或B的子类型。
想想List<? super B> list2 = new ArrayList<A/B>()
List<? super C>
类型可以是A,B,C。因此只有C是A,B或C的子类型。
例如,Machine
- &gt; Car
- &gt; SportsCar
。对于List<? super Machine>
,无论是Machine,Car还是SportsCar,它们都是机器,因此可以安全添加。