Java 理论和实践: 了解泛型
识别和避免学习使用泛型过程中的陷阱
简介: JDK 5.0 中增加的泛型类型,是 Java 语言中类型安全的一次重要改进。
但是,对于初次使用泛型类型的用户来说,泛型的某些方面看起来可能不容易明
白,甚至非常奇怪。在本月的“
Java 理论和实践
”中,Brian Goetz 分析了束
缚第一次使用泛型的用户的常见陷阱。您可以通过 讨论论坛与作者和其他读者
分享您对本文的看法。(也可以单击本文顶端或底端的 讨论来访问这个论坛。)
本文的标签: best_practices, generic, java, 应用开发, 理论和实践
发布日期: 2005 年 1 月 25 日
级别: 初级
访问情况 9772 次浏览
建议: 0 (添加评论)
平均分 (共 18 个评分 )
表面上看起来,无论语法还是应用的环境(比如容器类),泛型类型(或者泛型)
都类似于 C++ 中的模板。但是这种相似性仅限于表面,Java 语言中的泛型基本
上完全在编译器中实现,由编译器执行类型检查和类型推断,然后生成普通的非
泛型的字节码。这种实现技术称为
擦除(erasure)
(编译器使用泛型类型信息
保证类型安全,然后在生成字节码之前将其清除),这项技术有一些奇怪,并且
有时会带来一些令人迷惑的后果。虽然范型是 Java 类走向类型安全的一大步,
但是在学习使用泛型的过程中几乎肯定会遇到头痛(有时候让人无法忍受)的问
题。
注意:本文假设您对 JDK 5.0 中的范型有基本的了解。
泛型不是协变的
虽然将集合看作是数组的抽象会有所帮助,但是数组还有一些集合不具备的特殊
性质。Java 语言中的数组是协变的(covariant),也就是说,如果 Integer
扩展了 Number(事实也是如此),那么不仅 Integer 是 Number,而且 Integer[]
也是 Number[],在要求 Number[]的地方完全可以传递或者赋予 Integer[]。(更
正式地说,如果 Number 是 Integer 的超类型,那么 Number[]也是 Integer[]
的超类型)。您也许认为这一原理同样适用于泛型类型 —— List<Number>是
List<Integer>的超类型,那么可以在需要 List<Number>的地方传递
List<Integer>。不幸的是,情况并非如此。