繁体   English   中英

Java Generics — 将子类列表分配给超类列表

[英]Java Generics — Assigning a list of subclass to a list of superclass

我有一个关于将子类列表分配给超类列表的基本问题。

所以我有以下内容:

Class B extends A;

List <B> bList = new ArrayList<B>();
List <A> aList = bList; 

为什么最后一次分配失败? 对不起新手问题

当您声明 A 类型的项目列表时,只能从列表中添加或删除类型 A 的项目。 如果需要包含 A 的子类,请使用通用通配符? extends A ? extends A来表示。 因此,您的代码应为:

List <? extends A> aList = bList; 

为了解释这一点,让我用 Integer 代替“B”,用数字代替“A”。 这只是为了使它更容易解释。

Class Integer extends Number;

List <Integer> iList = new ArrayList<Integer>();
List <Number> nList = iList // will fail

这将失败的原因是因为 nList 可以采用任何数字——它可以采用 Integer,它可以采用 Double,或者就此而言,它可以采用 Number 的任何子类。 但是,对于 iList 来说,情况并非如此。 您不能将 Double 添加到 iList,因为它只接受 Integer 及其子类。 希望这有助于向您解释。

List<B>不是List<A>

通过示例:假设您有class B1 extends A{}class B2 extends A{}然后(如果您能够这样做:

List<B1> b1 = new AList<B1>();
List<A> a = b1;

List<B2> b2 = new AList<B2>();

根据假设,您应该能够执行 a.add(new B2()) 但这是错误的。

如果您尝试相同的操作但使用arrays而不是列表,它将在运行时编译并抛出异常。

我们说 arrays 是协变的,而 generics 是不变的。

让代码编译你有它的智慧:

List<? extends A> a = b;

这表示 a 是 A 的某个子类型的列表。_但你不知道是哪一个。 因此你不能做a.put(X)

List<B>List<A>invariant类型。 你需要的是covariant类型。 在这种情况下,它是List<? extends A> List<? extends A>

因为 generics 是严格类型安全的。

你可以有

List<? extends A> aList = bList;

它说aList可以保存任何类型的列表,它是A

因为List<B>不扩展List<A> 例如, Integer扩展NumberLong也是如此。 所以List<Number>可以同时包含IntegerLong 因此,如果您将List<Integer>分配给List<Number> ,您将能够将Long添加到您的整数列表中。

你可以声明

List<? super B> superB;

这将允许将包含 B 及其超类的任何列表分配给 superB。 但这与您的情况不同aList=bList

或者

List<? extends A> extendsA;

例子

    List<? super Integer> superA;
    superA = new ArrayList<Number>();

    List<? extends Number> extendsNumber;
    extendsNumber = new ArrayList<Integer>();

乍一看,您可能会认为

Class B extends A;

List <B> bList = new ArrayList<B>();
List <A> aList = bList;

应该可以工作,当您想象实际使用这些列表时,问题就很明显了:

A something = new A();
aList.add( something ); // Should work because aList is a list of A's

但是aList已分配给bList ,因此应该与

bList.add( something ); // Here's the problem

bList.add()接受B ,但somethingA ,而A不是B

这就是为什么 generics 应该(并且是)严格类型安全的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM