注册通行证 用户名 密码
  • 文章投稿
  • 博客
  • 论坛
  • 设为首页
  • 加入收藏
jztop.com网络技术
  • 首页
  • | iT新闻
  • | 操作系统
  • | 组网建网
  • | 网络安全
  • | 程序开发
  • | 办公一族
  • | 工具软件
  • | 网页制作
  • | 多媒体制作
  • | 网吧技术
  • | 服务器
  • | 专题教程
Vista | 软件评测 | 系统备份 | 优化 | 进程 | 聊天 | 病毒 | Linux | 黑客 | 防火墙 | 数据库 | Web开发 | Java | Word | 游戏 | 32位开发 | 移动开发
当前位置:首页 > 程序开发 > Java 内容正文:Java 理论与实践: 伪typedef反模式

Java 理论与实践: 伪typedef反模式

发布时间:2006-03-31 22:11:16 来源:ibm 网友评论 0 条
  将泛型添加到 Java 语言中增加了类型系统的复杂性,提高了许多变量和方法声明的冗长程度。因为没有提供 “typedef” 工具来定义类型的简短名称,所以有些开发人员转而把扩展当作 “穷人的 typedef”,结果收到了良好的效果。

  对于 Java 5.0 中新增的泛型工具,一个常见的抱怨就是,它使代码变得太冗长。原来用一行就够的变量声明不再存在了,与声明参数化类型有关的重复非常讨厌,特别是还没有良好地支持自动补足的 IDE。例如,如果想声明一个 Map,它的键是 Socket,值是 Future<String>,那么老方法就是:

Map socketOwner = new HashMap(); 

  比新方法紧凑得多:

 Map<Socket, Future<String>> socketOwner    = new HashMap<Socket, Future<String>>();   

  当然,新方法内置了更多类型信息,减少了编程错误,提高了程序的可读性,但是确实带来了更多声明变量和方法签名方面的前期工作。类型参数在声明和初始化中的重复看起来尤其没有必要;Socket 和 Future<String> 需要输入两次,这迫使我们违犯了 “DRY” 原则(不要重复自己)。

  合成类似于 typedef 的东西

  添加泛型给类型系统增加了一些复杂性。在 Java 5.0 之前,“type” 和 “class” 几乎是同义的,而参数化类型,特别是那些绑定的通配类型,使子类型和子类的概念有了显著区别。类型 ArrayList<?>、ArrayList<? extends Number> 和 ArrayList<Integer> 是不同的类型,虽然它们是由同一个类 ArrayList 实现的。这些类型构成了一个层次结构;ArrayList<?> 是 ArrayList<? extends Number> 的超类型,而 ArrayList<? extends Number> 是 ArrayList<Integer> 的超类型。

  对于原来的简单类型系统,像 C 的 typedef 这样的特性没有意义。但是对于更复杂的类型系统,typedef 工具可能会提供一些好处。不知是好还是坏,总之在泛型加入的时候,typedef 没有加入 Java 语言。

  有些人用作 “穷人的 typedef” 的一个(坏的)做法是一个小小的扩展:创建一个类,扩展泛型类型,但是不添加功能,例如 SocketUserMap 类型,如清单 1 所示:

  清单 1. 伪 typedef 反模式 —— 不要这么做

 public class SocketUserMap extends HashMap<Socket<Future<String>> { } SocketUserMap socketOwner = new SocketUserMap(); 

  我将这个技巧称为伪 typedef 反模式,它实现了将 socketOwner 定义简化为一行的这一(有问题的)目标,但是有些副作用,最终成为重用和维护的障碍。(对于有明确的构造函数而不是无参构造函数的类来说,派生类也需要声明每个构造函数,因为构造函数没有被继承。)

  伪类型的问题

  在 C 中,用 typedef 定义一个新类型更像是宏,而不是类型声明。定义等价类型的 typedef,可以与原始类型自由地互换。清单 2 显示了一个定义回调函数的示例,其中在签名中使用了一个 typedef,但是调用者提供给回调的是一个等价类型,而编译器和运行时都可以接受它:

  清单 2. C 语言的 typedef 示例
 // Define a type called "callback" that is a function pointer typedef void (*Callback)(int); void doSomething(Callback callback) { } // This function conforms to the type defined by Callback void callbackFunction(int arg) { } // So a caller can pass the address of callbackFunction to doSomething void useCallback() {   doSomething(&callbackFunction);  } 

  扩展不是类型定义

  用 Java 语言编写的试图使用伪 typedef 的等价程序就会出现麻烦。清单 3 的 StringList 和 UserList 类型都扩展了一个公共超类,但是它们不是等价的类型。这意味着任何想调用 lookupAll 的代码都必须传递一个 StringList,而不能是 List<String> 或 UserList。

  清单 3. 伪类型如何把客户限定在只能使用伪类型
 class StringList extends ArrayList<String> { } class UserList extends ArrayList<String> { } ... class SomeClass {     public void validateUsers(UserList users) { ... }     public UserList lookupAll(StringList names) { ... } } 

  这个限制要比初看上去严格得多。在小程序中,可能不会有太大差异,但是当程序变大的时候,使用伪类型的需求就会不断地造成问题。如果变量类型是 StringList,就不能给它分配普通的 List<String>,因为 List<String> 是 StringList 的超类型,所以不是 StringList。就像不能把 Object 分配给类型为 String 的变量一样,也不能把 List<String> 分配给类型为 StringList 的变量(但是,可以反过来,例如,可以把 StringList 分配给类型为 List<String> 的变量,因为 List<String> 是 StringList 的超类型。)

  同样的情况也适用于方法的参数;如果一个方法参数是 StringList 类型,那么就不能把普通的 List<String> 传递给它。这意味着,如果不要求这个方法的每次使用都使用伪类型,那么根本不能用伪类型作为方法参数,而这在实践当中就意味着在库 API 中根本就不能使用伪类型。而且大多数库 API 都源自本来没想成为库代码的那些代码,所以 “这个代码只是给我自己的,没有其他人会用它” 可不是个好借口(只要您的代码有一点儿用处,别人就有可能会使用它;如果您的代码臭得很,那您可能是对的)。
相关文章
  • 网站设计中的导航理论与实践
  • 简单Velocity实践
  • Velocity 为 Java Web 应用开发“增速”
  • Javascript:将人民币数字转换成大写形式
  • JAVA/JSP学习系列之一(JDK安装)
【评论】【收藏本文】【打印】【关闭】
上一篇文章:Java中正则表达式使用方法详解
下一篇文章:内存泄漏,走开 轻松搞定Java内存泄漏
讨论区
查看
已有 0 位对此新闻感兴趣的网友发表了看法
匿名发表
注册通行证 登陆
图文阅读推荐
Java控件设计入门
Java控件设计入门
推荐阅讯
  • 经验分享:如何迅速成为Java高手
  • 在Java中使用Draw2D和SWT绘图
  • 通过JDBC连接oracle数据库的十大技巧
  • JAVA对于数字证书的常用操作方法
  • 实战体会Java的多线程编程
  • Java设计模式之工厂方法模式
  • Java建立Zip压缩文件
  • 商业周刊:Java缘何开源迟迟
  • 跟我学Java Swing之游戏设计(1)
  • Java连接SQL Server 2000
阅读排行
  • 1.Java连接SQL Server 2000
  • 2.Java文件操作详解
  • 3.Java控件设计入门
  • 4.Java操作Excel电子表格
  • 5.Java: JNI完全手册
  • 6.Java命令行简介
  • 7.开发J2EE应用应遵循的几点原则
  • 8.Servlet与Javabean配置
  • 9.Java规则引擎与其API应用详解
  • 10.CLASSPATH详解
专题教程
  • 大话G游 专题:手机病毒揭密
  • ARP攻击防范与解决方案 路由故障处理手册
  • Picasa中文版_Picasa教程 专题:清除流氓软件
  • Firefox专题 seo搜索引擎优化专区
  • 重装Windows必知的事情 装机之必备软件大行动
病毒专杀栏
  • 杀毒软件反被病毒杀 连"救命"都不能喊
  • 金山ARP防火墙
  • 还原卡神话破灭“机器狗”病毒来势汹汹
  • cctv经济半小时:你的手机现在安全吗?
  • 新挂马方式开始流行 ARP挂马称雄局域网
  • 木马和病毒清除的通用解法
  • IP地址不再冲突 查找ARP攻击者元凶
  • 教你几招识别和防御Web网页木马
  • 分析:封杀BT只是暂时的止痛药
  • QQ爆危险漏洞,“QQ游戏邀请大盗”邀请你玩病
关于我们 | 诚聘英才 | 联系我们 | 版权声明 | 网站大事 | 网站地图 | 意见建议
CopyRight 2005-2007 Jztop.Com 版权所有 未经许可 请勿转载