Java 泛型 - 通过继承层的上限
Java Generics - Upper Bounds through layers of inheritance
通过单层继承,我可以做这样的事情:
// Dog extends Animal
List<Dog> dogs = ...;
// Cat extends Animal
List<Cat> cats = ...;
List<? extends Animal> animals = new ArrayList<>();
animals.addAll(cats);
animals.addAll(dogs);
我可以不用转换就可以做到这一点,这很好。
但是如果我遇到如下情况怎么办?
// Plant extends LivingBeing
List<Plant> plants = ...;
// Animal extends LivingBeing
// Cat extends Animal
List<Cat> cats = ...;
List<? extends LivingBeing> livingThings = new ArrayList<>();
// This is fine
lvingThings.addAll(plants);
// FIXME: Fails because Cat doesn't directly extend LivingBeing
livingThings.addAll(cats);
有没有办法指定一个不是列表所有成员的直接父级的上限,这样我就可以避免转换?
您的第一个示例无法编译。两者都是由 ? extends
部分引起的。问题是一旦初始化完成,编译器就已经忘记了实际类型。这意味着在初始化 livingThings
之后,编译器认为它可以是 List<LivingBeing>
、List<Animal>
或 List<Cat>
(所有这些都允许添加猫),但也可以是 List<Dog> or
List`,不允许猫。
如果你想要一个列表,其中包含可以是任何类型生物的事物,你必须这样声明它:List<LivingBeing>
。否则除了 null
.
之外你不能再添加任何东西
后者适用于任何 Collection<? extends T>
任何类型 T
。对于匹配 ? extends T
的任何类型,唯一安全的值是 null
.
通过单层继承,我可以做这样的事情:
// Dog extends Animal
List<Dog> dogs = ...;
// Cat extends Animal
List<Cat> cats = ...;
List<? extends Animal> animals = new ArrayList<>();
animals.addAll(cats);
animals.addAll(dogs);
我可以不用转换就可以做到这一点,这很好。
但是如果我遇到如下情况怎么办?
// Plant extends LivingBeing
List<Plant> plants = ...;
// Animal extends LivingBeing
// Cat extends Animal
List<Cat> cats = ...;
List<? extends LivingBeing> livingThings = new ArrayList<>();
// This is fine
lvingThings.addAll(plants);
// FIXME: Fails because Cat doesn't directly extend LivingBeing
livingThings.addAll(cats);
有没有办法指定一个不是列表所有成员的直接父级的上限,这样我就可以避免转换?
您的第一个示例无法编译。两者都是由 ? extends
部分引起的。问题是一旦初始化完成,编译器就已经忘记了实际类型。这意味着在初始化 livingThings
之后,编译器认为它可以是 List<LivingBeing>
、List<Animal>
或 List<Cat>
(所有这些都允许添加猫),但也可以是 List<Dog> or
List`,不允许猫。
如果你想要一个列表,其中包含可以是任何类型生物的事物,你必须这样声明它:List<LivingBeing>
。否则除了 null
.
后者适用于任何 Collection<? extends T>
任何类型 T
。对于匹配 ? extends T
的任何类型,唯一安全的值是 null
.