传递列表<子类>到需要 List的方法

发布于 2025-01-06 04:38:26 字数 418 浏览 1 评论 0原文

我有一个需要 List 作为参数的方法:

public void myMethod(List<SuperClass> list) {}

我想使用 List 调用该方法,例如:

List<SubClass> subList = new ArrayList<>();
// ...
myMethod(subList); // Got an argument mismatch error on this line.

我不应该能够当SubClass扩展SuperClass时执行此操作?

I have a method that is expecting a List<SuperClass> as argument:

public void myMethod(List<SuperClass> list) {}

I want to call that method with a List<Subclass> something like:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

無心 2025-01-13 04:38:26

不,泛型不是这样工作的。您可以做的是将您的方法定义为 MyMethod(List list) (按照惯例,它应该命名为 myMethod(...) 顺便说一句)。

ListList 的问题在于,您可以向此类列表添加新元素,而编译器不允许您向列表添加某些内容。 列表 - 这是有原因的:

请考虑以下事项:

class A {}

class B extends A {}

class C extends A {}

如果您现在有一个 List,您可以添加 A的实例>BC。但是,如果将 List 作为 List 参数,编译器不知道是否允许将 AC 的实例添加到该列表中(不允许,但如果您传递的是 List )。因此编译器限制你不要这样做。

将参数定义为 List 告诉编译器可以将所有三个类的实例放入该列表中。现在,如果您被允许传递 List 作为这样的参数,您最终可能会得到一个包含 A< 实例的 List /code> 和/或 C。这显然不是您想要的,并且可能会导致运行时错误,而这些错误应该在编译时通过使用泛型来预防。这就是为什么你的方法不起作用。

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).

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> - and this has a reason:

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. However, if you pass a List<B> to a method as 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). 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. 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. 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.

梅倚清风 2025-01-13 04:38:26

值得注意的是,您还可以从子类列表创建超类列表,如下所示:

myMethod(new ArrayList<SuperClass>(list));

Worth noting, you can also create the list of your superClass from a list of subClass as such:

myMethod(new ArrayList<SuperClass>(list));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文