在参数中使用泛型集合

f1d*_*ave 3 java generics collections inheritance

假设你有:

public interface A {}

public class B implements A {}

public class C {
  void foo (List<A>) {}
}

public class Test {
  //Declaration one
  List<A> x = new List<A>();

  //Declaration two
  List<A> x = new List<B>();

  B b = new B();
  x.add(b);


  new C().foo(x);
}
Run Code Online (Sandbox Code Playgroud)

现在显然声明一个是正确的方法,并且您在声明二上收到编译错误.我想知道为什么Java选择以这种特定的方式强制执行类型安全; 如果Cats的列表仍然是动物列表,为什么一个方法期待动物列表在收到一堆猫时不愿意?

好奇,最重要的是 - 并有机会更好地完善我的知识.

干杯,戴夫.

Oli*_*rth 9

Java泛型不是协变的.如果你能做到这一点:

ArrayList<Animal> x = new ArrayList<Cat>();
Run Code Online (Sandbox Code Playgroud)

那你就能做到:

x.add(new Dog());
Run Code Online (Sandbox Code Playgroud)

这违反了ArrayList<Cat>只能保存Cat对象(或子类对象)的概念.

阅读本文以获取更多详细信息:Java理论与实践:泛型陷阱.


Osw*_*ald 9

为什么一种方法期待动物名单在收到一堆猫时不愿意?

因为您可以将任何动物添加到该列表中,而不仅仅是猫.这可能会导致包含狗的猫的列表,如下所示:

我觉得有一个间谍我们...

呼叫者仍然认为这是一个猫和一只狗的名单,当呼叫者试图让他们跌倒时,他们会摔倒.