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

2018-10-20 15:38:40 +08:00
 abcbuzhiming
因为掉在 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>拿到容器容器内部元素的类型的,难道此时类型擦除没生效?

最重要的是,为什么继承之后就保留住了泛型容器内部的类型?这是什么原理?
2294 次点击
所在节点    Java
5 条回复
alamaya
2018-10-20 15:50:11 +08:00
java 中子类可以获取到父类泛型的真实类型,TypeReference 也好 TypeToken 也好都是基于这个原理,因为 class 会保存父类的泛型信息,运行时则会被擦除
feiyuanqiu
2018-10-20 15:53:02 +08:00
xuanbg
2018-10-20 18:31:44 +08:00
基类型是泛型,继承类型还是泛型。类型 T 不过就是个参数而已,继承下来还是参数。
aristotll
2018-10-20 20:28:04 +08:00
泛型的信息在编译时是保留的 在运行的时候是擦除的
ca1123
2018-10-22 01:22:07 +08:00
我始终没搞清楚擦除和泛型的关系。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/499422

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX