V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abcbuzhiming
V2EX  ›  Java

当我继承自一个给定类型的泛型容器时,得到的类型还是泛型吗?

  •  
  •   abcbuzhiming · 2018-10-20 15:38:40 +08:00 · 2398 次点击
    这是一个创建于 2230 天前的主题,其中的信息可能已经有所发展或是发生改变。
    因为掉在 Java 泛型实现里的坑,我撞上了这个问题
    https://www.v2ex.com/t/498842
    这个问题承蒙大家解答,确认最终就是 Java 泛型实现是类型擦除导致的坑,而且看来看去,除非采用一些比较特殊的方法传递额外参数,反正你就是没法在名为 T 的占位符位置传输类似 List<ClassName>这样的精确类型。

    但是 @deming 提出了一个神奇的方案:继承
    public class ClassNameList extends ArrayList<ClassName>

    然后用继承得到的这个 ClassNameList 类型,这个类型可以完美的放入 T 占位符里,而且也能执行 ClassName.class 这样的操作。也能被 Jackson2JsonRedisSerializer<CustomerInfoList> serializer 使用并且成功的反序列化,反序列化得到的结果可以赋值给 List<ClassName>。并且 List<ClassName>中的元素取出后可以执行各种 ClassName 的操作。也就是说这个转换完全是成功的。

    于是我就开始困惑了,这个继承了 ArrayList<ClassName>的 ClassNameList,它自身算是个泛型类吗?貌似不是?它没有 T 这种类型参数,但是它自身是一个泛型类的子类,而且,转换过程中是必须去父类 ArrayList<ClassName>拿到容器容器内部元素的类型的,难道此时类型擦除没生效?

    最重要的是,为什么继承之后就保留住了泛型容器内部的类型?这是什么原理?
    5 条回复    2018-10-22 01:22:07 +08:00
    alamaya
        1
    alamaya  
       2018-10-20 15:50:11 +08:00
    java 中子类可以获取到父类泛型的真实类型,TypeReference 也好 TypeToken 也好都是基于这个原理,因为 class 会保存父类的泛型信息,运行时则会被擦除
    xuanbg
        3
    xuanbg  
       2018-10-20 18:31:44 +08:00
    基类型是泛型,继承类型还是泛型。类型 T 不过就是个参数而已,继承下来还是参数。
    aristotll
        4
    aristotll  
       2018-10-20 20:28:04 +08:00
    泛型的信息在编译时是保留的 在运行的时候是擦除的
    ca1123
        5
    ca1123  
       2018-10-22 01:22:07 +08:00
    我始终没搞清楚擦除和泛型的关系。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1029 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 22:18 · PVG 06:18 · LAX 14:18 · JFK 17:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.