首页 / 软件开发 / JAVA / 诊断Java代码: 轻松掌握Java泛型类型,第2部分
诊断Java代码: 轻松掌握Java泛型类型,第2部分2011-02-11 IBM Eric E. AllenJ2SE 1.5 ― 代号为“Tiger” ― 计划在 2003 年年底发布,它将包括泛型类型(如在 JSR-14 原型编译器中预先展示的那样,现在可下载获得)。在 第 1 部分中,我们讨论了泛型类型的基础知识,以及为什么它们是对 Java 语言的一个重要且迫切需要的补充。我们还说明了为 Tiger 制定的泛型类型的实现怎么会包含数个“缺陷”,这些缺陷限制了可以使用泛型类型的上下文。为了帮助新程序员有效地使用泛型类型,我将详细说明到底泛型类型的哪些用法在 Tiger 和 JSR-14 中是被禁止的,并将说明为什么这些限制是 JSR-14(理所当然还有 Tiger)为了在 JVM 上兼容地实现泛型类型所使用的实现策略的必然结果。泛型类型的限制让我们先查阅一下 Tiger 和 JSR-14 中泛型类型的使用限制:不应在静态成员中引用封闭类型参数。不能用基本类型实例化泛型类型参数。不能在数据类型转换或 instanceof 操作中使用“外露”类型参数。不能在 new 操作中使用“外露”类型参数。不能在类定义的 implements 或 extends 子句中使用“外露”类型参数。为什么会有这些限制呢?这要归因于 Tiger 和 JSR-14 为在 JVM 上实现泛型类型所使用的机制。由于 JVM 根本不支持泛型类型,所以这些编译器“耍了个花招”,使得似乎存在对泛型类型的支持 ― 它们用泛型类型信息检查所有的代码,但随即“擦除”所有的泛型类型并生成只包含普通类型的类文件。例如,将象 List<T> 这样的泛型类型擦除得只剩下 List 。“外露”类型参数 ― 单独出现而不是位于某个类型中的类型参数(如类 List<T> 中的类型参数 T )― 被简单地擦除成它们的上界(就 T 而言,其上界就是 Object )。这一技术的功能极其强大;我们可以使几乎所有泛型类型的精度得到增强,但又与 JVM 保持兼容。事实上,我们甚至可以交替地使用非泛型的旧类(比如 List )和其对应的泛型类( List<T> );两者在运行时看起来是一样的。遗憾的是,正如以上的限制所示,获得这一功能是有代价的。以这种方式进行擦除在类型系统中引入了缺陷,这些缺陷限制我们使用泛型类型的安全性。为了帮助说明每种限制,我们查阅会出现这些限制的示例。在本文中,我们将讨论前三个限制。与后两个限制有关的问题过于复杂,因而需要更深入的研究,留待下一篇文章讨论。静态成员中的封闭类型参数编译器完全禁止在静态方法和静态内部类中引用封闭类型参数。所以,举例来说,以下代码在 Tiger 中就是非法的:清单 1. 在静态上下文中非法引用封闭类型参数class C<T> {
static void m() {
T t;
}
static class D {
C<T> t;
}
}