将对象添加到“”延伸“类型的通用集合 [英] Adding objects to the "? extends" type of Generic Collections

查看:105
本文介绍了将对象添加到“”延伸“类型的通用集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public void addAllAnimals(ArrayList< ;? extends Animal> animalLikeList){

//我需要添加动物对象到动物列表。

}

我知道它不允许直接添加? extends Animal 代表 Animal 的未知子类型。

我的问题是:没有任何方式(间接方式)添加 addAll 动物动物的子类型< ?

解决方案

不,没有直接的法律途径(除了不安全的类型转换)。您只能向使用 super 而不是 extends 声明的通用集合添加元素。这可以更容易记住,由Josh Bloch在 Effective Java,第2版项目28中普及的缩写 PECS (Producer- Extends,Consumer- p>

事实上你看起来似乎并不直接。 A 列表<? extends Animal> 可以是列表< Dog> 列表< Cat> 。前者只能接受 Dog 元素,后者只有 Cat 。因为你不能在Java中实例化通用(不可恢复)类型,所以你必须在运行时知道你正在处理一个狗列表,所以你只试图向它添加狗(反之亦然)。这意味着你不能在本地和静态创建要添加的对象 - 你必须以通用的方式获得它们,此外,允许编译器确保每次具体类型匹配。最简单的方法是将元素作为通用参数传递。所以这是可能和安全的做到这一点:

  public& void addAllAnimals(List< E> animalLikeList,E animal){
animalLikeList.add(animal);
}

List< Dog> dogs = new ArrayList< Dog>();
List< Cat> cats = new ArrayList< Cat>();

addAllAnimals(dogs,new Dog());
addAllAnimals(cats,new Cat());

请注意,此方法是通用的,带有一个命名类型参数,该列表与要添加到其中的元素类型相同。



您可以简单地替换 E 参数与集合< E> 一次添加多个对象。


public void addAllAnimals(ArrayList<? extends Animal> animalLikeList){

 // I need to add animal objects (eg Dog, Cat that extends Animal) to animalLikeList.

}

I know that it doesn't allow to add directly since ? extends Animal stands for unknown sub type of the Animal.

My question is : Isn't there any way (indirect way) to add or addAll an Animal or a SubType of Animal object to the animalLikeList ?

解决方案

No, there is no direct legal way (apart from unsafe type casts). You can only add elements to a generic collection declared with super, not extends. This may be easier to remember with the acronym PECS (Producer - Extends, Consumer - Super), popularized by Josh Bloch in Effective Java, 2nd Edition, Item 28.

In fact what you seem to be after doesn't seem to make direct sense. A List<? extends Animal> can be e.g. a List<Dog> or a List<Cat>. The former can only accept Dog elements, the latter only Cats. And since you can't instantiate generic (nonreifiable) types in Java, you must know at runtime that you are dealing with a list of dogs, so you only attempt to add dogs to it (and vice versa for cats). That means you can't locally and statically create the objects to be added - you must get them in a generic way too, and moreover in a way which allows the compiler to ensure that the concrete types match each time. The simplest way for this is to pass the element(s) as a generic parameter. So it is possible and safe to do this:

public <E extends Animal> void addAllAnimals(List<E> animalLikeList, E animal) {
    animalLikeList.add(animal);
}

List<Dog> dogs = new ArrayList<Dog>();
List<Cat> cats = new ArrayList<Cat>();

addAllAnimals(dogs, new Dog());
addAllAnimals(cats, new Cat());

Note that this method is generic, with a named type parameter, which ensures that the actual generic type of the list is the same as the element type to be added to it.

You can trivially replace the E parameter with a Collection<E> to add several objects at once.

这篇关于将对象添加到“”延伸“类型的通用集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆