诊断Java代码: 轻松掌握 Java 泛型,第4部分 - 编程入门网
指出,与上月讨论的泛型类型的功能扩展一样,通过使用由 JSR-14 和 Tiger 使用的简单 类型消除(type erasure)策略,不能将对 mixin 的支持添加到 Java 语言中。
要了解其原因,请考虑在继承类型参数的类被消除时会出现什么情况。该类会最终继承类型参数的 界限!例如,上一个示例中类 Scrollable 的每个实例化最终都继承类 JComponent 。那显然不是我们所希望的。 为了通过泛型类型支持 mixin,我们 需要获得泛型类型实例化的运行时表示。幸运的是,编码这一信息的方法有许多,它们实际上都向后与 Tiger 兼容。 可用的超类构造函数 在我们希望允许类继承类型参数时立即出现的紧迫问题是要决定我们能调用什么样的超级构造函数?请回忆:每个 Java 类构造函数都必须调用超类的构造函数。通常,通过查找超类并确保存在匹配的超级构造函数,类型检查器确保这些超级构造函数调用会成功。 但是在我们对超类所知的一切只限于它是类型参数的实例化时,对于什么样的构造函数可用于给定的实例化,我们没有任何概念。而且请注意,类型检查器甚至不能检查是否每个 mixin 实例化都会产生有效的超级构造函数调用。其原因是:在某些其它上下文中,mixin 的参数可能用类型参数界限实例化了。 例如,泛型类 JSplitPane<T> 可以创建 Scrollable<T> 的实例。除非我们知道将类型参数 T 实例化为 JSplitPanes 的一切方法,否则我们不能知道在 Scrollable<T> 中调用的超级构造函数是否有效。但是因为 Java 编码允许单独的类编译,所以在类型检查期间,我们不能知道 JSplitPane 的所有实例。 解决这一问题的各种方案与我们上月 第 3 部分中讨论的针对检查 new 表达式的类型参数所提出的解决方案完全一致,因为超级构造函数调用和 new 表达式都引用了给定类的同一个类构造函数。让我们回顾一下这些解决方案: 需要一个不带参数的(zeroary)构造函数,用于所有类型参数的实例化。 当没有匹配的构造函数时,抛出运行时异常。 包含额外的类型参数注释,告知我们这些实例化必须包含哪些构造函数。 就如 new 表达式的情况,前两个解决方案有严重缺陷。通常在类定义中包含不带参数的构造函数没有任何意义。而且,当不存在任何匹配的构造函数时就抛出异常也不太理想。毕竟静态类型检查主要是严格防止那种异常。 第三种解决方案可能有点繁琐,但是它有许多优点。注释类型参数,其中包括所有实例化都必须拥有的构造函数集。这些注释确切地告知我们针对类型参数,我们可以可靠地调用什么样的构造函数。因此,当类型参数 T 用作泛型类的超类时, T 的注释确切地告知我们可以调用哪些超级构造函数。如果 T 不包含注释,那么类型检查器会禁止它用作超类。 意外的方法覆盖 任何 mixin 公式都会产生一个非常严重的问题:特定 mixin 的方法名可能与其超类的潜在实例化的方法名冲突。例如,假设类 Scrollable 包含不带任何参数的方法 getSize 并返回一个 Size 对象,编码了其水平和垂直尺寸。现在,我们假设类 MyTextPane ( JComponent 的子类)也包含不带任何参数的方法 getSize ,但返回一个 int ,表示调用它的对象的屏幕面积。 诊断Java代码: 轻松掌握 Java 泛型,第4部分(3)时间:2011-02-11 IBM Eric E. Allen产生的类显示如下: 清单 1. 意外方法覆盖的示例
随后 mixin 实例化 Scrollable<MyTextPane> 会包含两个带有同样(空)参数类型的方法 getSize ,但返回类型不一致!因为我们不能指望类 Scrollable 的 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |