[英]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
扩展Number
, Long
也是如此。 所以List<Number>
可以同时包含Integer
和Long
。 因此,如果您将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
,但something
是A
,而A
不是B
!
这就是为什么 generics 应该(并且是)严格类型安全的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.