gpt4 book ai didi

Java 泛型 : adding wrong type in collection

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:18:31 24 4
gpt4 key购买 nike

谁能解释一下?

我有这两个类:

abstract class Animal {
public void eat() {
System.out.println("Animal is eating");
}
}

class Dog extends Animal {
public void woof() {
System.out.println("woof");
}
}

class Cat extends Animal {
public void meow() {
System.out.println("meow");
}
}

这是 Action :

import java.util.ArrayList;
import java.util.List;

public class TestClass {

public static void main(String[] args) {
new TestClass().go();
}

public void go() {
List<Dog> animals = new ArrayList<Dog>();
animals.add(new Dog());
animals.add(new Dog());
doAction(animals);
}

public <T extends Animal> void doAction(List<T> animals) {

animals.add((T) new Cat()); // why is it possible?
// Variable **animals** is List<Dog>,
// it is wrong, that I can add a Cat!

for (Animal animal: animals) {
if (animal instanceof Cat) {
((Cat)animal).meow();
}
if (animal instanceof Dog) {
((Dog)animal).woof();
}
}
}
}

这个例子编译没有错误,输出是:

woof
woof
meow

但是我怎样才能在 Dog a Cat 列表中添加呢?以及如何将 Cat 转换为 Dog?

我使用:Java 版本“1.6.0_24”。 OpenJDK 运行环境(IcedTea6 1.11.1) (6b24-1.11.1-4ubuntu3)

最佳答案

好的,这是关于泛型的处理(任何使用转换黑客的东西在运行时可能都不安全,因为泛型通过 erasure 工作):

您可以使用相同的方式分配参数化的子类型,例如

List<Animal> l = new ArrayList<Animal>();

并且您可以添加此参数类型或其子类的项目,例如

l.add(new Cat());
l.add(new Dog());

但是只能取出参数的类型:

Animal a = l.get(0);
Cat c = l.get(0); //disallowed
Dog d = l.get(1); //disallowed

现在,您可以使用通配符来设置参数类型的上限

List<? extends Animal> l = new ArrayList<Animal>();
List<? extends Animal> l = new ArrayList<Cat>();
List<? extends Animal> l = new ArrayList<Dog>();

但是你不能向这个列表中添加新的项目

l.add(new Cat()); // disallowed
l.add(new Dog()); // disallowed

在你的例子中你有一个 List<T>所以它有一个方法 add(T t)所以如果你转换到T你可以添加.但是T类型以 Animal 为界所以你甚至不应该尝试添加到这个列表,但它被视为具体类型,这就是它允许转换的原因。但是这可能会抛出 ClassCastException .

而且你只能检索上限类型的项目

Animal a = l.get(0);
Cat c = l.get(0); //disallowed
Dog d = l.get(1); //disallowed

或者你可以设置下界参数类型

List<? super Animal> l1 = new ArrayList<Object>();
List<? super Animal> l1 = new ArrayList<Animal>();
List<? super Cat> l2 = new ArrayList<Animal>();
List<? super Cat> l2 = new ArrayList<Cat>();
List<? super Dog> l3 = new ArrayList<Animal>();
List<? super Dog> l3 = new ArrayList<Dog>();

并且您可以添加作为下限类型子类型的对象

l1.add(new Cat());
l1.add(new Dog());
l1.add(new Object()); //disallowed

但是检索到的所有对象都是Object类型

Object o = l1.get(0);
Animal a = l1.get(0); //disallowed
Cat c = l2.get(0); //disallowed
Dog d = l3.get(0); //disallowed

关于Java 泛型 : adding wrong type in collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10743810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com