ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 轻松掌握 Java 泛型 (第 4 部分)

轻松掌握 Java 泛型 (第 4 部分)

原创 Linux操作系统 作者:kirinri 时间:2008-01-10 18:04:06 0 删除 编辑

轻松掌握 Java 泛型 (第 4 部分)
来源:** 收集整理

 
 
 
 
 
  Java 开发人员和研究
的影响,并以此文来结束他
在相关论坛中与作者及其他
论”来访问该论坛。)至此
已经探讨了:
 人员 Eric Allen 讨论了通过泛
对 JSR-14 和 Tiger 中泛型类
读者分享您对本文的看法。(您
,在这个讨论 JSR-14 和 Tiger

 型类型添加对 mixin 支持所带来
型的由四部分组成的系列的讨论。
也可以单击本文顶部或底部的“讨
中泛型类型的微型系列中,我们

 

  泛型类型及被设计成支持它们的即将发布的功能                                    

  基本类型、受约束的泛型以及多态方法上的限制                                    

  几个强加给这些 Java 扩展的限制                                          

  这些扩展语言的编译器所用的实现策略如何使这些限制成为必需                      

  在泛型类型中添加对“裸”类型参数的 new 操作的支持所带来的影响            

  本月,我们将探讨在可
先解决的问题,以此来结束
 以处理 mixin(可能被期望是泛
对 Java 语言中泛型类型的讨论
 型类型中最强大的功能)之前需要

 

  mixin vs 包装                                                        
  mixin 是由其父类参数
数:
 化的类。例如,请考虑以下这个

 泛型类,它继承了它本身的类型参

 

  class Scrollable< T> extends T {...}


  不要错过本系列的其它文章                                                      

  第 1 部分,轻松掌握 Java 泛型(2003 年 2 月)               

  第 2 部分,轻松掌握 Java 泛型类
 型,第 2 部分(2003 年 3 月)
 

  第 3 部分,轻松掌握 Java 泛型,第 3 部分(2003 年 4 月) 

  类 Scrollable 的目的是要向 GUI 窗口小部件嵌入添加可滚动性所必需的功能性。这个泛型类的每个应用都会继承一个不同的父类。例如,Scrollable< JTextPane> 是 JTextPane 的子类,而 Scrollable< JEditorPane> 是 JEditorPane 的子类。对比这种嵌入功能的方法和 Java Swing 库中现有的功能性,在这个库中,如果我们想使 JComponent 是可滚动的,必须将其“包装”在 JScrollPane 中。


  包装不仅需要添加访问被包装类的功
的实例的上下文中使用由此产生的可滚动
JTextPane 的实例的方法中)。通过 Scr
们就能保持对涉及滚动的功能的单点控制
的某些强大功能,而又没有附带异常。
 能的转发方法,而且它还阻止我们在需要被包装对象
对象(例如,我们不能将 JScrollPane 传递到需要
ollable 的父类将其参数化,在继承多个超类时,我
。这样能够使用 mixin 让我们重新获得多重继承性

 

  在上面的示例中,我们
如,我们可能想使该类型参
 甚至可以对类型参数施加约束以
数强制为 JComponent 的子类:
 阻止它用于不适当的上下文中。例

 

  class Scrollable< T extends JComponent> extends T {...}


  那么我们的 mixin 只能继承 GUI 组件。                              

  mixin 和泛型类:完美组合                                               
  通常,mixin 作为独立语言功能部件
mixin 以作为泛型类型系统的一部分很吸
类都能被认为是将现有类映射到新类的函
 添加到某种语言中,就象 Jam 中的那样。但是合并
引人,几乎可以说魅力无穷。原因是:mixin 和泛型
数。
 

  泛型类可被视为将它们
子类的函数。通过使用泛型
 的参数映射成新实例化的函数。
类型合并 mixin,我们能解决其
 mixin 可被视为将现有类映射成新
它 mixin 公式的许多关键限制。
 

  在 Java 语言的 Jam
中引用它。这一限制会迅速
this 作为参数传递给方法
多最常见的设计模式都要依
 扩展中,mixin 的超类类型没有
引起一连串各种其它问题。例如
;无法对这样的调用进行类型检
赖于能够将 this 作为参数传递
 名称;我们就不能在 mixin 主体
,在 Jam 中,禁止程序员将
查。这一限制的影响极大,因为许

 

  请考虑访问者模式,其
常被访问的类包含 accept
在 Jam 中,访问者模式不
 中用 for 方法为复合层次结构
方法,它采用访问者并传递 thi
能和 mixin 一起使用。
 中的每个类都定义了访问者类。通
s 来调用该访问者的方法。因此,

 

  将 mixin 明确表述为泛型类,我们
如,我们可以将 Scrollable 的父类引用
传递时没有任何根本性的困难。
 就始终有父类的句柄,它是该类继承的类型参数。例
为类型 T。其结果是,在允许将 this 作为类型参数

 

  但是,将 mixin 明确表述为泛型类
产生的某些困难,我们将讨论几个突出的
 型时有其它一些明显的困难。为了让您初步体会可能
困难以及一些可能的解决方案。
 

  mixin 与类型消除                                                        
  在讨论任何其它问题之
过使用由 JSR-14 和 Tiger
支持添加到 Java 语言中。
 前,我们应该先指出,与上月讨
使用的简单类型消除(type er

 论的泛型类型的功能扩展一样,通
asure)策略,不能将对 mixin 的

 

  要了解其原因,请考虑
型参数的界限!例如,上一
。那显然不是我们所希望的
 在继承类型参数的类被消除时会
个示例中类 Scrollable 的每个

 出现什么情况。该类会最终继承类
实例化最终都继承类 JComponent

 

  为了通过泛型类型支持 mixin,我们
编码这一信息的方法有许多,它们实际上
泛型 Java(Generic Java)的 NextGen
 需要获得泛型类型实例化的运行时表示。幸运的是,
都向后与 Tiger 兼容。这样的向后兼容编码方案是
公式的显著特点(在参考资料一节中)。
 

  可用的超类构造函数                                                            
  在我们希望允许类继承
构造函数?请回忆:每个 J
并确保存在匹配的超级构造
 类型参数时立即出现的紧迫问题
ava 类构造函数都必须调用超类
函数,类型检查器确保这些超级
 是要决定我们能调用什么样的超级
的构造函数。通常,通过查找超类
构造函数调用会成功。
 

  但是在我们对超类所知
用于给定的实例化,我们没
mixin 实例化都会产生有效
参数可能用类型参数界限实
 的一切只限于它是类型参数的实
有任何概念。而且请注意,类型
的超级构造函数调用。其原因是
例化了。
 例化时,对于什么样的构造函数可
检查器甚至不能检查是否每个
:在某些其它上下文中,mixin 的

 

  例如,泛型类 JSplitPane< T> 可以创建 Scrollable< T> 的实例。除非我们知道将类型参数 T 实例化为 JSplitPanes 的一切方法,否则我们不能知道在 Scrollable< T> 中调用的超级构造函数是否有效。但是因为 Java 编码允许单独的类编译,所以在类型检查期间,我们不能知道 JSplitPane 的所有实例。


  解决这一问题的各种方案与我们上月
所提出的解决方案完全一致,因为超级构
类构造函数。让我们回顾一下这些解决方
 第 3 部分中讨论的针对检查 new 表达式的类型参数
造函数调用和 new 表达式都引用了给定类的同一个
案:
 

  需要一个不带参数的(zeroary)构造函数,用于所有类型参数的实例化。     
  当没有匹配的构造函数时,抛出运行时异常。                                     
  包含额外的类型参数注释,告知我们这些实例化必须包含哪些构造函数。             
  就如 new 表达式的情
构造函数没有任何意义。而
静态类型检查主要是严格防
 况,前两个解决方案有严重缺陷
且,当不存在任何匹配的构造函
止那种异常。
 。通常在类定义中包含不带参数的
数时就抛出异常也不太理想。毕竟

 

  第三种解决方案可能有点繁琐,但是
都必须拥有的构造函数集。这些注释确切
样的构造函数。因此,当类型参数 T 用
用哪些超级构造函数。如果 T 不包含注
 它有许多优点。注释类型参数,其中包括所有实例化
地告知我们针对类型参数,我们可以可靠地调用什么
作泛型类的超类时,T 的注释确切地告知我们可以调
释,那么类型检查器会禁止它用作超类。
 

  意外的方法覆盖                                                                
  任何 mixin 公式都会
潜在实例化的方法名冲突。
返回一个 Size 对象,编码
JComponent 的子类)也包
对象的屏幕面积。
 产生一个非常严重的问题:特定
例如,假设类 Scrollable 包含
了其水平和垂直尺寸。现在,我
含不带任何参数的方法 getSize

 mixin 的方法名可能与其超类的
不带任何参数的方法 getSize 并
们假设类 MyTextPane(
,但返回一个 int,表示调用它的

 

  产生的类显示如下:                                                            

  清单 1. 意外方法覆盖的示例                                                

  class Scrollable< T extends JComponent> extends T { 

   ...                                                                     
   Size getSize() {...}                                    
  }                                                                            

  class MyTextPane extends JComponent {   
   ...                                                                     
   int getSize() {...}                                      
  }                                                                            

  new Scrollable< MyTextPane>() 


  随后 mixin 实例化 Scrollable< MyTextPane> 会包含两个带有同样(空)参数类型的方法 getSize,但返回类型不一致!因为我们不能指望类 Scrollable 的程序员或 MyTextPane 的程序员预见这个有问题的 getSize 覆盖(毕竟,他们甚至不可能在同一个开发团队),因此我们称之为意外覆盖。


  当 mixin 被明确表述
用类型参数被实例化,因此
盖出现时抛出运行时异常是
如果我们想编写可靠的程序
 为泛型类时,意外覆盖的问题特
类型检查器就不能确定意外方法
无法接受的,因为客户机程序员
,那么我们必须禁止在运行时出
 别讨厌。因为 mixin 的父类可能
覆盖的所有情况。而且,在意外覆
无法预测何时将抛出这样的异常。
现无法预料的错误。
 

  另一个解决方案是只隐藏这些相互冲突的方法中的一个,并解析所有匹配的方法调用以引用未隐藏的方法。这个解决方案的问题是我们希望诸如 Scrollable< MyTextPane> 这样的 mixin 实例化可用于调用 Scrollable 对象的上下文以及调用 MyTextPane 对象的上下文中。隐藏 getSize 方法中的任一个都会在这两个上下文中禁止使用 Scrollable< MyTextPane>。


  在 1998 年召开的有关编程语言原理
上,Felleisen、Flatt 和 Krishnamurth
该问题的一个好的解决方案:基于使用 m
用。在这个解决方案中,mixin 包含有这
法。
 的 ACM SIGPLAN-SIGACT 研讨会(请参阅参考资料)
i 提出了在 mixin 不属于泛型类型的上下文中针对
ixin 实例化的上下文来解决对相互冲突的方法的引
样的观点:确定在名称不一致的情况中要调用哪个方

 

  在 mixin 作为泛型类
点,这些观点在泛型类型的
室中,我们已经在“A Firs
出了这样一种解决方案。
 型的情况中,我们可以应用同样
上下文中有效,并且还允许向后
t-Class Approach to Generici

 的解决方案。我们只要设计一些观
兼容 JVM。在 Rice JavaPLT 实验
ty”(请参阅参考资料)一文中提

 

  有得必有失                                                                    
  正如示例、问题和可能的解决方案所
mixin 的支持会产生一种功能强大的语言
编程语言设计:只能通过使许多现有功能
没有任何免费的午餐。
 
 
发表于:2004.12.24 16:54

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12476590/viewspace-133987/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2007-12-21

  • 博文量
    257
  • 访问量
    501202