[英]Passing List<Subclass> to method expecting List<SuperClass>
I have a method that is expecting a List<SuperClass>
as argument: 我有一个方法,希望使用
List<SuperClass>
作为参数:
public void myMethod(List<SuperClass> list) {}
I want to call that method with a List<Subclass>
something like: 我想用
List<Subclass>
调用该方法,例如:
List<SubClass> subList = new ArrayList<>();
// ...
myMethod(subList); // Got an argument mismatch error on this line.
Shouldn't I be able to do this when SubClass extends SuperClass
? 当
SubClass extends SuperClass
时,我不能这样做吗?
No, generics don't work like that. 不,泛型不能那样工作。 What you could do is define your method as
MyMethod(List<? extends SuperClass> list)
(by convention it should be named myMethod(...)
btw). 您可以做的是将您的方法定义为
MyMethod(List<? extends SuperClass> list)
(按照惯例,它应命名为myMethod(...)
btw))。
The problem with List<SuperClass>
vs. List<SubClass>
is that you could add new elements to such lists whereas the compiler wouldn't allow you to add something to a List<? extends SuperClass>
List<SuperClass>
与List<SubClass>
的问题在于您可以向此类列表添加新元素,而编译器不允许您向List<? extends SuperClass>
添加某些内容List<? extends SuperClass>
List<? extends SuperClass>
- and this has a reason: List<? extends SuperClass>
-这是有原因的:
Consider the following: 考虑以下:
class A {}
class B extends A {}
class C extends A {}
If you now have a List<A>
you could add instances of A
, B
and C
. 如果现在有了
List<A>
,则可以添加A
, B
和C
实例。 However, if you pass a List<B>
to a method as a List<? extends A>
但是,如果您将
List<B>
作为List<? extends A>
传递给方法List<? extends A>
List<? extends A>
parameter, the compiler doesn't know whether it is allowed to add instances of A
or C
to that list (it wouldn't be allowed, but in case you'd pass a List<A>
it would be). List<? extends A>
参数,编译器不知道是否允许将A
或C
实例添加到该列表(不允许这样做,但是如果您要传递List<A>
则可以)。 Thus the compiler restricts you not to do so. 因此,编译器限制您不要这样做。
Defining a parameter as List<A>
tells the compiler that is is ok to put instances of all three classes to that list. 将参数定义为
List<A>
告诉编译器可以将所有三个类的实例放入该列表。 Now if you would be allowed to pass a List<B>
as such a parameter you could end up with a List<B>
that contains instances of A
and/or C
. 现在,如果允许您传递
List<B>
作为这样的参数,您可能会以包含A
和/或C
实例的List<B>
结尾。 And this is clearly not what you want and could result in runtime bugs that should be prevented at compile time already - by using generics. 而且这显然不是您想要的,并且可能会导致运行时错误,应在编译时通过使用泛型来避免这些错误。 That's why your approach doesn't work.
这就是为什么您的方法行不通的原因。
值得注意的是,您还可以像这样从子类列表中创建超类列表:
myMethod(new ArrayList<SuperClass>(list));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.