Kyr*_*iev 7 java generics bounded-wildcard
谁能解释一下这个?
我有几个班:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
这就是行动:
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子编译没有错误,输出是:
woof
woof
meow
Run Code Online (Sandbox Code Playgroud)
但是我如何添加Dog a Cat列表呢?那猫如何被送到狗?
我用的是:java版"1.6.0_24".OpenJDK运行时环境(IcedTea6 1.11.1)(6b24-1.11.1-4ubuntu3)
好的,这是与泛型的交易(任何使用cast hackery的东西在运行时可能都不安全,因为泛型通过擦除工作):
您可以以相同的方式分配参数化的子类型,例如
List<Animal> l = new ArrayList<Animal>();
Run Code Online (Sandbox Code Playgroud)
并且您可以添加作为此参数的类型或其子类的项目,例如
l.add(new Cat());
l.add(new Dog());
Run Code Online (Sandbox Code Playgroud)
但你只能得到参数的类型:
Animal a = l.get(0);
Cat c = l.get(0); //disallowed
Dog d = l.get(1); //disallowed
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用通配符设置参数类型的上限
List<? extends Animal> l = new ArrayList<Animal>();
List<? extends Animal> l = new ArrayList<Cat>();
List<? extends Animal> l = new ArrayList<Dog>();
Run Code Online (Sandbox Code Playgroud)
但是您无法在此列表中添加新项目
l.add(new Cat()); // disallowed
l.add(new Dog()); // disallowed
Run Code Online (Sandbox Code Playgroud)
在你的情况下,你有一个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
Run Code Online (Sandbox Code Playgroud)
或者您可以设置下限参数类型
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>();
Run Code Online (Sandbox Code Playgroud)
并且您可以添加作为下限类型的子类型的对象
l1.add(new Cat());
l1.add(new Dog());
l1.add(new Object()); //disallowed
Run Code Online (Sandbox Code Playgroud)
但是检索的所有对象都是Object类型
Object o = l1.get(0);
Animal a = l1.get(0); //disallowed
Cat c = l2.get(0); //disallowed
Dog d = l3.get(0); //disallowed
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1815 次 |
最近记录: |