简体   繁体   English

Java-将对象多态传递给接受通用参数的方法

[英]Java - Passing objects polymorphically to methods accepting Generic arguments

I was reading "Head First Java" - pretty cool book to get started on Java. 我正在阅读《 Head First Java》,这是一本非常不错的入门Java书籍。 I have a question with regards to Generics. 我对泛型有疑问。

The book had correctly stated that it is not possible to polymorphically pass a subtype to method accepting ArrayList. 该书正确地指出,不可能将子类型多态地传递给接受ArrayList的方法。 Example below - 下面的例子-

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) {

    }

}

However the above can be fixed by the use of generics - 但是,上述问题可以通过使用泛型来解决-

public <T extends Animal> void processAnimals(List<T> animalList) {

}

But in the above case compiler would throw an exception if anything is tried to be added to the list (this is mentioned in the book). 但是在上述情况下,如果尝试将任何内容添加到列表中,编译器都会抛出异常(本书中对此进行了提及)。 I tried it using my IDE and it did thrown an exception. 我使用IDE对其进行了尝试,但确实引发了异常。 The book had also mentioned that this is to ensure incorrect objects(eg cat) from being added to the list (dogList in our case). 该书还提到这是为了确保将不正确的对象(例如cat)添加到列表(在我们的例子中是dogList)。

However I am able to do this by casting the cat / dog / animal object using (T). 但是我可以通过使用(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
}

As per the book, the whole reason why Java creators threw an exception is because incorrect object should not be added to the list. 根据这本书,Java创建者抛出异常的全部原因是因为不应将不正确的对象添加到列表中。 However is Java allowing it because the programmer is explicitly casting it and thereby saying "I know what I am doing"? 但是Java是否允许它,因为程序员正在显式地强制转换它并说“我知道自己在做什么”?

Basically, you did an end run on the compiler. 基本上,您在编译器上完成了运行。

You have to think about the entire point of Generics. 您必须考虑泛型的整个要点。 They are there for compile-time safety ONLY. 它们仅用于编译时安全。 They buy you nothing else. 他们什么都没买。 At runtime, due to type erasure, you're still dealing with a List<Object> , which can hold anything. 在运行时,由于类型擦除,您仍在处理List<Object> ,它可以容纳任何内容。 If you decided to explicitly cast something, then the compiler won't second guess you. 如果您决定显式转换某些内容,那么编译器将不会再猜测您。 You've moved the potential danger from compile time to runtime, which is your choice. 您已将潜在危险从编译时转移到了运行时,这是您的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM