诊断Java代码: 轻松掌握Java泛型,第3部分 - 编程入门网
诊断Java代码: 轻松掌握Java泛型,第3部分时间:2011-02-11 IBM Eric E. Allen这一系列主要讨论在 Java 编程中添加泛型类型,本文是其中的一篇,将研究还未讨论过的有关使用泛型的两个限制之一,即添加对裸类型参数的 new 操作的支持(如类 C<T> 中的 new T() )。 正如我 上个月所提到的那样,Tiger 和 JSR-14 通过使用“类型消除(type erasure)”对 Java 语言实现泛型类型。使用类型消除(type erasure),泛型类型仅用于类型检查;然后,用它们的上界替换它们。由此定义可知:消除将与如 new T() 之类的表达式冲突。 如果假定 T 的界限是 Object ,那么这一表达式将被消除为 new Object() ,并且不管对 T 如何实例化( String 、 List 、 URLClassLoader 等等), new 操作将产生一个新的 Object 实例。显然,这不是我们想要的。 要添加对表达式(如 new T() )的支持,以及添加对我们上次讨论过的其它与类型相关的操作(如数据类型转换和 instanceof 表达式)的支持,我们必须采用某种实现策略而不是类型消除(如对于每个泛型实例化,使用独立的类)。但对于 new 操作,需要处理其它问题。 尤其是,为了实现对 Java 语言添加这种支持,必须对许多基本的语言设计问题作出决定。 有效的构造函数调用 首先,为了对类型参数构造合法的 new 表达式(如 new T() ),必须确保我们调用的构造函数对于 T 的每个实例化都有效。但由于我们只知道 T 是其已声明界限的子类型,所以我们不知道 T 的某一实例化将有什么构造函数。要解决这一问题,可以用下述三种方法之一: 要求类型参数的所有实例化都包括不带参数的(zeroary)构造函数。 只要泛型类的运行时实例化没有包括所需的构造函数,就抛出异常。 修改语言的语法以包括更详尽的类型参数界限。 第 1 种方法:需要不带参数的构造函数 只要求类型参数的所有实例化都包括不带参数的构造函数。该解决方案的优点是非常简单。使用这种方法也有先例。 处理类似问题的现有 Java 技术(象 JavaBean 技术)就是通过要求一个不带参数的构造函数来解决问题的。然而,该方法的一个主要缺点是:对于许多类,没有合理的不带参数的构造函数。 例如,表示非空容器的任何类在构造函数中必然使用表示其元素的参数。包括不带参数的构造函数将迫使我们先创建实例,然后再进行本来可以在构造函数调用中完成的初始化。但该实践会导致问题的产生(您可能想要阅读 2002 年 4 月发表的本专栏文章“The Run-on Initializer bug pattern”,以获取详细信息;请参阅 参考资料。) 第 2 种方法:当缺少所需构造函数时,抛出异常 处理该问题的另一种方法是:只要泛型类的运行时实例化没有包括所需构造函数,就抛出异常。请注意:必须在运行时抛出异常。因为 Java 语言的递增式编译模型,所以我们无法静态地确定所有将在运行时发生的泛型类的实例化。例如,假设我们有如下一组泛型类: 清单 1.“裸”类型参数的 New 操作
诊断Java代码: 轻松掌握Java泛型,第3部分(2)时间:2011-02-11 IBM Eric E. Allen现在,在类 D<S> 中,构造了类 C<S> 的实例。然后,在类 C 的主体中,将调用 S 的不带参数的构造函数。这种不带参数的构造函数存在吗?答案当然取决于 S 的实例化! 比方说,如果 S 被实例化为 String ,那么答案是“存在”。如果它被实例化为 Integer ,那么答案是“不存在”。但是,当编译类 D 和 C 时,我们不知道其它类会构造什么样的 D<S> 实 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |