类型继承问题

Type Inheritance Issue

我真的不知道如何解释我遇到的问题。下面是我拥有的一些对象的示例。

假设我有 类

public class Foo{}
public class FooBar extends Foo{}

所有这一切都很好,但是如果我拿一个列表并说我希望它充满 Foo 个对象,我不能为它提供 FooBar 个对象。这是为什么?

示例:

List<Foo> fooList = Arrays.asList(new FooBar());

如果FooBar extends Foo,为什么不能转换回Foo

Arrays.asList(new FooBar())returns一个List<FooBar>,不能赋值给一个List<Foo>。如果它可以分配给它,那么您可以创建一个 List<FooBar>,将其分配给 List<Foo>,然后将 Foo 添加到必须包含 FooBar 的列表中明显是错误的。

相反,您需要:

List<Foo> fooList = new ArrayList<>();
fooList.add(new FooBar());

如评论中所述Arrays.asList(T...) returns List<T>。由于您将 FooBar 实例传递给了 Java 7 中的方法类型推断,因此使用 FooBar 类型作为 T 表示,这意味着此方法 returns List<FooBar>无法分配给 List<Foo>(您可以在以下位置阅读更多信息:Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?

在 Java 8 中改进了类型推断,使 lambda 更有用。现在 T 不仅从参数推断类型,而且从目标 - 应该保存结果的引用变量推断类型。这允许 TList<Foo> fooList 而不是 new FooBar() 参数推断 Foo

要在早期版本中解决此问题,例如您的情况 Java 7,您可以 显式 为泛型方法 asList 设置泛型类型 [=26] =]

List<Foo> fooList = Arrays.<Foo>asList(new FooBar());
//                         ^^^^^ -- set generic types before method name

更多信息位于:https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html(尤其是 "Target Types" 部分)