[英]Java - Passing objects polymorphically to methods accepting Generic arguments
我正在阅读《 Head First Java》,这是一本非常不错的入门Java书籍。 我对泛型有疑问。
该书正确地指出,不可能将子类型多态地传递给接受ArrayList的方法。 下面的例子-
public class Animal {
}
public class Dog extends Animal {
}
public class Cat extends Animal {
}
public class AnimalTester {
public static void main (String[] args) {
new AnimalTester().go();
}
public void go() {
List<Animal> animalList=new ArrayList<Animal>();
List<Dog> dogList=new ArrayList<Dog>();
processAnimals(animalList); // this would compile
processAnimals(dogList); // this would not compile
}
public void processAnimals(List<Animal> animalList) {
}
}
但是,上述问题可以通过使用泛型来解决-
public <T extends Animal> void processAnimals(List<T> animalList) {
}
但是在上述情况下,如果尝试将任何内容添加到列表中,编译器都会抛出异常(本书中对此进行了提及)。 我使用IDE对其进行了尝试,但确实引发了异常。 该书还提到这是为了确保将不正确的对象(例如cat)添加到列表(在我们的例子中是dogList)。
但是我可以通过使用(T)投射猫/狗/动物物体来做到这一点。
public <T extends Animal> void processAnimals(List<T> animalList) {
animalList.add(new Animal()); // compilation Error
animalList.add(new Dog()); // compilation Error
animalList.add(new Cat()); // compilation Error
animalList.add((T) new Cat()); // works and I can also cast it back
// to Cat and get a Cat object
}
根据这本书,Java创建者抛出异常的全部原因是因为不应将不正确的对象添加到列表中。 但是Java是否允许它,因为程序员正在显式地强制转换它并说“我知道自己在做什么”?
基本上,您在编译器上完成了运行。
您必须考虑泛型的整个要点。 它们仅用于编译时安全。 他们什么都没买。 在运行时,由于类型擦除,您仍在处理List<Object>
,它可以容纳任何内容。 如果您决定显式转换某些内容,那么编译器将不会再猜测您。 您已将潜在危险从编译时转移到了运行时,这是您的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.