首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仿制药和遗传?

仿制药和遗传?
EN

Stack Overflow用户
提问于 2015-05-15 12:50:11
回答 3查看 130关注 0票数 3
代码语言:javascript
复制
public static void main(String... args) {
    List<Child> list1 = new ArrayList<Child>();
    method2(list1);
}

public static void method2(List<Parent> list1) {
}   

我得到以下编译错误

方法method2(列表)未定义.

上述问题可以通过将List<Parent> list1修改为List<? extends Parent> list1来解决。

但是,如果我尝试添加如下所示的子对象

代码语言:javascript
复制
public static void method2(List<? extends Parent> list1) {
    Child child1 = new Child();
    list1.add(child1);
}

它再次给出编译错误。

方法添加(捕获#1-of?)类型列表中的扩展父类)不适用于参数(子)

所以我的问题是,如果List<Child>可以作为参数传递给List<? extends Parent> list1,为什么我们不能在List<? extends Parent>下添加子对象

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-15 12:57:07

这是一个很常见的误解。子扩展父级并不使List<Child>扩展List<Parent>。在这种情况下听起来很不直观,但就是这样。来自java教程:

给定两个具体类型A和B(例如,Number和Integer),MyClass< A>与MyClass< B>没有关系,无论A和B是否相关。MyClass和MyClass的共同父级是Object。

详细信息请阅读

至于添加到列表中,简单的回答是:假设您有另一个class Child2 extends Parent,现在,您在method2(List<? extends Parent> list1)作为参数接收的列表可以是List<Child1>List<Child2>。因此,假设第二种情况是可能的,那么添加一个Child1对象是不安全的。

现在,您不能添加的事实并不意味着您不能做其他有用的东西,如大小,等等。

票数 6
EN

Stack Overflow用户

发布于 2015-05-15 13:16:18

所以我的问题是,如果List<Child>可以作为参数传递给List<? extends Parent> list1,为什么不能在List<? extends Parent>下添加子对象呢?

假设我们可以。现在假设我们有:

代码语言:javascript
复制
class Parent {}
class Mother extends Parent {}
class Father extends Parent {}

static void m(List<? extends Parent> parents) {
    parents.add(new Father());
}

List<Mother> mothers = new ArrayList<>();
m(mothers);
// throws 'ClassCastException: cannot cast Father to Mother'
Mother actuallyAFather = mothers.get(0);

List<? extends Parent>是最多存储Parent的列表,也可能是Parent的某些子类型,我们已经不知道这些子类型了。除了null之外,我们不能向它添加任何内容。

所以也许你想要的是:

代码语言:javascript
复制
public static void method2(List<? super Child> list1) {
//                                ^^^^^^^^^^^
    Child child1 = new Child();
    list1.add(child1);
}

List<? super Child>是一个列表,我们可以向其中添加一个Child。可能是List<Parent>,也可能是List<Child>,但我们不在乎。我们只关心这是一个可以添加Child的列表。

另见:

票数 1
EN

Stack Overflow用户

发布于 2015-05-16 15:08:15

,这是我自己读了更多东西后的答案,

我们不能分配List<Dog> to List<Animal>,因为List<Animal>意味着我们可以向它添加任何动物,如猫、狗,而List<Dog>则意味着我们只能向它添加狗/子类型,而不能添加猫。所以分配者会认为他只会得到狗/子类型,但是他也可以得到cat对象(所以运行时错误)。

下面是一个例子

代码语言:javascript
复制
psvm{
List<Dog> list1 = new ArrayList<Dog>();
list1.add(new Dog()); 
method1(list1);// compilation error
}

public static void method1(List<Animal> list1) {
list1.add(cat); // Good
list1.add(dog); // Good
}

另一个常见的误解是关于上界泛型的,它正好相反。

当我们说List<? extends Animal> list1时,除了null之外,我们不能添加任何值,但是是的,如果允许添加它,我们可以分配任何动物/子类型,这意味着它可以包含任何动物,比如猫、狗,但是在检索(即向下转换)时,我们不知道它实际上是什么类型。

代码语言:javascript
复制
psvm{
List<Dog> list1 = new ArrayList<Dog>();
list1.add(new Dog()); 
method1(list1);// good
}

public static void method1(List<? extends Animal> list1) {
list1.add(cat); // compilation error
list1.add(dog); // compilation error
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30259985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档