诊断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. 在静态上下文中非法引用封闭类型参数
诊断Java代码: 轻松掌握Java泛型类型,第2部分(2)时间:2011-02-11 IBM Eric E. Allen当编译这一代码时,会生成两个错误: 在静态方法 m 中非法引用 T 的错误 在静态类 D 中非法引用 T 的错误 当定义静态字段时,情况变得更加复杂。在 JSR-14 和 Tiger 中,在泛型类的所有实例中共享该类中的静态字段。现在,在 JSR-14 编译器 1.0 和 1.2 中,如果您在静态字段声明中引用类型参数,编译器不会报错,但它本应该这么做。字段被共享这一事实很容易在运行时导致奇怪的错误,如在不包含数据类型转换的代码中出现 ClassCastException 。 例如,以下程序将在这两个版本的 JSR-14 下通过编译而没有任何警告: 清单 2. 在静态字段中对封闭类型参数的有问题的引用
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |