List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的?| Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看活动链接

List 是List 的子类吗?为什么Java泛型不是隐式多态的?

我对Java泛型如何处理继承/多态感到困惑。

假设以下层次结构-

动物(父类)

狗-猫(子类)

因此,假设我有一个方法doSomething(List animals)。通过将所有继承和多态的规则,我会假设List 是一个List和List 是一个List-所以任何一个可以传递给此方法。不是这样 如果要实现此行为,则必须通过说出明确告诉该方法接受Animal的任何子类的列表doSomething(List<? extends Animal> animals)。

我了解这是Java的行为。我的问题是为什么?为什么多态性通常是隐式的,但是当涉及泛型时,必须指定它?

高分回答:

很多的知识点,真的需要写出来才会掌握!!! \color{purple}很多的知识点,真的需要写出来才会掌握!!!{~}

不,List是不是一个List。考虑一下您可以做什么List-您可以向其中添加任何动物…包括猫。现在,您可以在逻辑上将猫添加到一窝小狗中吗?绝对不。

// Illegal code - because otherwise life would be Bad
List<Dog> dogs = new ArrayList<Dog>(); // ArrayList implements List
List<Animal> animals = dogs; // Awooga awooga
animals.add(new Cat());
Dog dog = dogs.get(0); // This should be safe, right?
复制代码

相反的情况是正确的List<? super Animal>-在这种情况下,您可以Animal安全地向其中添加一个,但是对于从中检索到的内容一无所知,因为它可能是个List。

高分回答:

要理解该问题,与数组进行比较很有用。

List<Dog>是不是子类List<Animal>。
但是 Dog[] 是的子类Animal[]。
复制代码

数组是可校正且协变的。(作者也不知这是什么词–大概意思就是数组可以向上转型)

可修复意味着它们的类型信息在运行时完全可用。

因此,数组提供运行时类型安全性,但不提供编译时类型安全性。

    // All compiles but throws ArrayStoreException at runtime at last line
    Dog[] dogs = new Dog[10];
    Animal[] animals = dogs; // compiles
    animals[0] = new Cat(); // throws ArrayStoreException at runtime
复制代码

反之,

泛型则相反:泛型被擦除且不变。

因此,泛型不能提供运行时类型安全性,但是它们可以提供编译时类型安全性。

在下面的代码中,如果泛型是协变的,则有可能在第3行造成堆污染。

    List<Dog> dogs = new ArrayList<>();
    List<Animal> animals = dogs; // compile-time error, otherwise heap pollution
    animals.add(new Cat());
复制代码

文章翻译自 am2dgbqfb6mk75jcyanzabc67y-ac4c6men2g7xr2a-stackoverflow-com.translate.goog/questions/2…

作者建议: 这肯定不行啊,它是一个List

看到了一句话:

Java泛型是编译器泛型,是一种语法,生成的二进制代码中是没有泛型的,jvm感受不到泛型。java的泛型编译生成二进制代码的时候,进行了类型的擦除,放入集合的实际上是object类型,从集合中获取对象的时候 获取的是object类型, 然后进行了强制类型转换,转换成实际的类型。

欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!! \color{red}欢迎关注我的专栏StackOverFlow,我会筛选优质的问答,面试常考!!!{~}

有最新、优雅的实现方式,我也会在文末写出我对本问答的见解 \color{red}有最新、优雅的实现方式,我也会在文末写出我对本问答的见解{~}

真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话

求点赞? 求关注❤️ 求分享? 对8块腹肌的我来说真的 非常有用!!!

如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享