Csdn Java电子杂志第2期

3,007 views

Published on

Published in: Technology, Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,007
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
18
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Csdn Java电子杂志第2期

  1. 1. 《CSDN 社区电子杂志——Java 杂志》 目录 目录 ..........................................................................................................................................i 读者反馈 ............................................................................................................................ - 1 - 热点新闻 ............................................................................................................................ - 4 - 新品发布 ............................................................................................................................ - 4 - 1.1. BEA WebLogic Server 9.0 测试版发布.............................................................................- 4 - 1.2. Hibernate3 发布beta版本 支持EJB3 风格对象持久化.....................................................- 4 - 1.3. JBoss 4 应用服务器指南文档发布 ....................................................................................- 5 - 业界动态 ............................................................................................................................ - 6 - 1.1. IBM为开源献上免费午餐 无偿开放 500 件专利 ............................................................- 6 - 1.2. 诺基亚与沃达丰携手 拟制订手机Java行业标准.............................................................- 7 - 年度盘点 ............................................................................................................................ - 8 - 技术专题—J2SE 5.0 新特性精解 ................................................................................... - 11 - 升级到J2SE 5 平台的 5 大理由 ...................................................................................... - 11 - 1.1. 以前的应用程序可以直接在 5.0 上运行.........................................................................- 11 - 1.1.1. 改进的性能 ...........................................................................................................- 11 - 1.1.2. 监控和易管理性 ...................................................................................................- 11 - 1.1.3. 新的观感 ...............................................................................................................- 12 - 1.2. 速度更快 ...........................................................................................................................- 12 - 1.2.1. 缩短启动时间 .......................................................................................................- 12 - 1.2.2. 卓越的 64 位性能 .................................................................................................- 12 - 1.2.3. 性能改善 ...............................................................................................................- 13 - 1.3. 缩短开发时间 ...................................................................................................................- 13 - 1.3.1. 减少开发人员编码数量 .......................................................................................- 13 - 1.3.2. 增强的错误检验存储 ...........................................................................................- 14 - 1.4. 适用于任务关键型系统 ...................................................................................................- 14 - 1.4.1. 可伸缩性 ...............................................................................................................- 14 - http://emag.csdn.net i 2005 年 1 月 1 期 总第 2 期
  2. 2. 《CSDN 社区电子杂志——Java 杂志》 1.4.2. 质量 .......................................................................................................................- 14 - 1.4.3. 部署 .......................................................................................................................- 15 - 1.5. 您选择了一家优秀的公司 ...............................................................................................- 15 - 1.5.1. 有关J2SE 5.0 的图书 ............................................................................................- 15 - 1.6. 结束语 ...............................................................................................................................- 16 - Tiger核心库简介 .............................................................................................................. - 17 - 1.1. 事务的属性 .......................................................................................................................- 17 - 1.1.1. 访问环境变量 .......................................................................................................- 17 - 1.1.2. 访问子进程 ...........................................................................................................- 18 - 1.2. 并发集合 ...........................................................................................................................- 19 - 1.2.1. Queue接口.............................................................................................................- 19 - 1.2.2. ConcurrentMap实现 ..............................................................................................- 23 - 1.2.3. CopyOnWriteArrayList 和 CopyOnWriteArraySet.............................................- 24 - 1.3. Formatter ...........................................................................................................................- 25 - 1.3.1. PrintStream支持 ....................................................................................................- 27 - 1.3.2. String支持..............................................................................................................- 28 - 1.3.3. 格式化任意对象 ...................................................................................................- 28 - 1.4. 从XML文件中装载属性...................................................................................................- 30 - 1.4.1. XML属性文件 ......................................................................................................- 30 - 1.4.2. 存取XML属性文件...............................................................................................- 31 - 1.5. 其他核心库的增强 ...........................................................................................................- 32 - 1.5.1. Scanner ..................................................................................................................- 32 - 1.5.2. JavaBeans组件体系结构.......................................................................................- 32 - 1.5.3. Math包...................................................................................................................- 33 - 1.5.4. 网络 .......................................................................................................................- 33 - 1.5.5. 安全性 ...................................................................................................................- 33 - 1.5.6. 国际化 ...................................................................................................................- 33 - 1.5.7. 序列化 ...................................................................................................................- 34 - 1.6. 结束语 ...............................................................................................................................- 34 - JAVA泛型QUIK START .................................................................................................. - 35 - http://emag.csdn.net ii 2005 年 1 月 1 期 总第 2 期
  3. 3. 《CSDN 社区电子杂志——Java 杂志》 1.1. JAVA泛型 ..........................................................................................................................- 35 - 1.1.1. 泛型通配符 ...........................................................................................................- 36 - 1.1.2. 编写泛型类要注意: ...........................................................................................- 36 - 1.2. 泛型与数据类型转换 .......................................................................................................- 37 - 1.2.1. 消除类型转换 .......................................................................................................- 37 - 1.2.2. 自动解包装与自动包装的功能............................................................................- 38 - 1.2.3. 限制泛型中类型参数的范围................................................................................- 38 - 1.2.4. 多态方法 ...............................................................................................................- 39 - J2SE 5.0 专题 之 用户接口 ........................................................................................... - 40 - 1.1. 引子 ...................................................................................................................................- 40 - 1.2. 综述 ...................................................................................................................................- 40 - 1.3. 国际化 ...............................................................................................................................- 41 - 1.4. Java声音技术 ....................................................................................................................- 42 - 1.5. Java 2D技术及图像 I/O ...................................................................................................- 43 - 1.5.1. AWT与Swing ........................................................................................................- 43 - 1.6. 结束语 ...............................................................................................................................- 46 - J2SE 5.0 专题 之 语言特性 ........................................................................................... - 47 - 1.1. 背景 ...................................................................................................................................- 47 - 1.2. 准备工作 ...........................................................................................................................- 47 - 1.3. 概述 ...................................................................................................................................- 48 - 1.4. 泛型 ...................................................................................................................................- 49 - 1.5. 增强的for循环...................................................................................................................- 51 - 1.6. 自动装箱/自动拆箱 ..........................................................................................................- 53 - 1.7. 类型安全的枚举 ...............................................................................................................- 54 - 1.8. 可变长度参数 ...................................................................................................................- 56 - 1.9. 静态引入 ...........................................................................................................................- 56 - 1.10. 元数据(注解) ...........................................................................................................- 57 - 1.11. C风格格式化输出.............................................................................................................- 59 - 1.12. 结语 ...............................................................................................................................- 60 - J2SE 5.0 新特性 之 线程 ............................................................................................... - 61 - http://emag.csdn.net iii 2005 年 1 月 1 期 总第 2 期
  4. 4. 《CSDN 社区电子杂志——Java 杂志》 1.1. 进程、线程与线程池 .......................................................................................................- 61 - 1.2. Java的线程概述 ................................................................................................................- 61 - 1.3. Collection部分的扩容.......................................................................................................- 62 - 1.3.1. Queue 接口...........................................................................................................- 62 - 1.3.2. List、Set、Map接口.............................................................................................- 65 - 1.4. 线程池 ...............................................................................................................................- 66 - 1.4.1. FutureResult 实例.................................................................................................- 68 - 1.4.2. 使用 FutureResult 来改善高速缓存 ...................................................................- 69 - 1.5. 结束语 ...............................................................................................................................- 70 - MetaData Programme ....................................................................................................... - 71 - 1.1. 什么是元数据编程 ...........................................................................................................- 71 - 1.2. Annotation的意义和简单例子 .........................................................................................- 71 - 1.3. Annotation的class文件格式..............................................................................................- 72 - 1.4. 为什么需要Annotation .....................................................................................................- 76 - 1.5. 再议Annotation .................................................................................................................- 77 - 1.6. 元数据编程的应用: .......................................................................................................- 78 - 1.7. 结束语: ...........................................................................................................................- 81 - 思考题 .............................................................................................................................. - 82 - http://emag.csdn.net iv 2005 年 1 月 1 期 总第 2 期
  5. 5. 《CSDN 社区电子杂志——Java 杂志》 读者反馈 Java 电子杂志第一期发布已经有一个月的时间了,这期间我们收到了好多热心读者的意见和建 议,下面是一些读者的反馈: 首先,我要感谢 CSDN 的各位编辑能在百忙之中,抽出时间为我们献上了这么好的杂志。 内容十分的不错,图片很漂亮。但是,还是不免有不少问题: 1. 文章中的错误很多,大多是拼写的错误,要么丢字,要么多字,让人感觉起来就想 是应付差事似的,希望能在发稿前多检查两边。 2. 排版不是太好,感觉有些插图摆放的不是太好,页面也被切的乱七八糟,代码片段 几乎没有一点格式可言。程序员本应该很重视的代码规范在这里面完全无法体现出 来,没有了缩进的代码开起来实在是很不舒服,也不美观。 3. 一些建议:希望能在没篇文章后做一个标记之类的结束符,说明文章已经结束,要 不然感觉非常的生硬; 4. 另外,个人不太喜欢这种左右分栏,看起来不舒服,还是不分栏比较习惯;文章中 的连接,不知道为什么没有办法直接点击,我看过的一些书都是按下 ctrl+鼠标左键 点击连接的,不知道你们是怎么实现的。 提的问题比较多,还请各位编辑见谅。总体上说,这期杂志还是不错的,能看出来我们 的编辑同志还是花了不少心思的。感谢各位编辑带给我们的精彩内容,希望下一期杂志 能更加精彩。 作为一个初学者角度来讲,作为创号刊应该: 1. 注重阐述 Java 的发展历史、趋向,让人真正了解 Java 2. 应用方面(吸引更多人来学习) 3. 应该对专业术语进行讲解,为以后更好的学习提供基础 能不能出一些针对 java web 应用测试的教程。比如如何用软件做 java 内存泄露检查。如 何发现我们程序的漏洞,程序运行效率的瓶颈。大家把相关的经验都拿出来,我想对大 家开发工作会有很大的帮助。 创刊号令我惊讶,总体感觉相当不错,出乎我的意料之外。页与页之间的插图有些选得 很棒。希望以后能保持水准,坚持下去。把 java 杂志做成最好的电子杂志。 http://emag.csdn.net -1- 2005 年 1 月 1 期 总第 2 期
  6. 6. 《CSDN 社区电子杂志——Java 杂志》 希望有深入一些的文章.其中有很多只不过是从网上看到的英文再译一下.能不能写一些 完整的项目开发经验之类的. 不错,很值得期待的一本杂志。这可能是国内首创的专门针对 JAVA 技术的杂志,如果可 能发行的话,我一定订阅。能否在杂志中增加一些连载? 设个小专栏,发表大家的简短学习心得. 很高兴能有这样一份杂志出来,我很喜欢。我有一个小小的建议:每页分栏我感觉很不 方便,看完一栏还得向上滚动才能开始看,没有一页就是一栏看起来舒服。期待着下一 期的到来 我在阅读电子杂志,感觉排版对阅读不是很方便,看起来比较累,我不知道这本杂志除 了电子版之外,还有其他方式,如果没有,我觉得完成可以充分利用技术将各个信息整 理成一个目录,方便查阅。在内容上,我建议可以将一个高手的成长经历总结出来让其 他程序员分享。JAVA 现在应用越来越普通,但随着各种技术和规范层出不穷,给程序员 选择构架时,不知所措,所以建议多增加这方面的内容。 我今天下载了 CSDN Java 电子杂志创刊号,觉得内容不错!可是我觉得你们是否可以少 放点图片,多些实质的内容这样可以缩减文件大小,而且让读者看着舒服!我觉得你们 可以在每期都出一道 java 程序设计的题目,然后在后一次公布答案!这样读者可以实践 自己的所学。谢谢!希望你们的杂志越办越好! 很高兴看到了第一期 java 电子杂志,看了一些杂志的开头,感觉杂志办的很专业,内容 也很不错,希望这份 java 的电子杂志能继续办下去,并且办的越来越好。下面就对杂志 提几点自己小的小的看法:看了一下电子杂志,感觉排版做的有点不太好,我指的是, 《struts 最佳实践》这篇文章,对于文章中出现的程序代码,希望排版的时候能把代码整 理的让人比较容易看懂,就是不要象杂志中出现的,本来可以写在一行的代码因为,但 是在排版的时候,被排到了好几行,让人不是很容易就看懂代码。还有就是在同一篇文 章里面有一段 jsp 代码也是排版排的不太好,感觉看起来不太容易。另外就是在杂志的正 文中出现的图片,图片倒是很好看,但是感觉有的地方图片太大了,有点喧宾夺主的感 觉。上面说了那么多主要还是一个排版版面的问题,就是希望出现代码的地方能够排版 的时候能排的整齐一些,让读者可以容易看一些。还有就是关于杂志的内容,能不能就 是以后的文章每期能以专题的形式来介绍一些 java 开源的比较流行的 framework 和技术。 比如象 spring framework,struts,webworks,hibnate,eclipse,jboss,ant,junit 等比较热 门的技术。然后杂志的内容呢希望多能偏中一些设计的思想的层面的介绍,比如现在热 http://emag.csdn.net -2- 2005 年 1 月 1 期 总第 2 期
  7. 7. 《CSDN 社区电子杂志——Java 杂志》 门的 design pattern,ood ,oop 的介绍。好了现在能想起来就上面那么多了,祝 java 电子 杂志能越办越好。各位杂志的编辑 happy new year! 刚下载了一期,觉得不错有两点觉得不方便: 1. pdf 文档分栏,阅读十分不便,建议不要分栏 2. 能不能附源码 对于以上意见我们在这里就不一一解答了,我们在做杂志的时候一定会认真接受读者提出的意 见的, 在此对所有关心,关注,支持 java 电子杂志的读者以及网友表示感谢,希望大家能够一如既往 的支持电子杂志,也希望大家能够积极的反馈意见,踊跃的投稿,电子杂志的发展离不开大家的参 与!CSDN 关于 java 电子杂志创刊号的调查的结果已经统计出来了,我放到 Java 电子杂志官方 Blog 的里了,大家可以到这个地址查看: http://blog.csdn.net/emag_java/archive/2005/01/28/271486.aspx,也 欢迎大家到电子杂志的 Blog 已及 emag 站点上了解杂志的最新情况,发表您的意见和建议。 《CSDN 社区电子杂志——Java 杂志》编辑部 2005 年 1 月 http://emag.csdn.net -3- 2005 年 1 月 1 期 总第 2 期
  8. 8. 《CSDN 社区电子杂志——Java 杂志》 热点新闻 新品发布 1.1. BEA WebLogic Server 9.0 测试版发布 BEA WebLogic Server 9.0 测试版以于日前提供免费下载。WebLogic 一直是全球 j2ee 领域强大 的只得信赖的应用程序服务器,这次的 9.0 测试版也不例外,甚至更强。这次的这个测试版是基于 j2ee 1.4 标准,优点包括:扩展了新的管理员控制台,通过框架和脚本诊断工具使管理员能够及时 的发现和解决出现的问题。使 Web 服务在应用程序中支持异步的消息传递机制。等等。 测试版下载地址: http://commerce.bea.com/index.jsp 1.2. Hibernate3 发布 beta 版本 支持 EJB3 风格对象持 久化 12 月 20 日 Hibernate 框架发布了 3.0 版本的第一个 beta 版本。据作者 Gavin King 表示,Hibernate 3.0 将于明年(2005 年)第一季度正式发布。Hibernate 是一个基于 POJO(Plain-Old Java Object, 普通 Java 对象)的 O/R mapping 框架,也是目前 J2EE 社群最流行的对象持久化工具。正在制订中 的 EJB3 规范就大量借鉴了 Hibernate 的经验。 在 beta1 版本中,Hibernate3 并未提供对 J2SE 5.0 的支持,这主要是因为出于兼容性的考虑。 Gavin King 表示,将在 2005 年逐步引入 J2SE 5.0 提供的新语言特性,例如泛型、元数据标注等。 Hibernate3 主要的新特性包括: 实现了 EJB3 风格的持久化操作。在原有的 saveOrUpdate()和 saveOrUpdateCopy()两个方法之 外,又提供了 EJB3 风格的 create()和 merge()两个操作。 提供更强的映射灵活性。允许将一个类映射到多张表,允许混合使用“每个继承体系一张表” 和“每个子类一张表”的映射策略,等等。 支持存储过程和手写 SQL,并且可以用手写 SQL 替代 Hibernate 自动生成的 SQL 语句。 基于 AST(抽象语法树)的 HQL 解析。 字段级的懒式获取。每个属性都可以在映射描述符中声明“lazy=true” ,这样声明的属性会到 http://emag.csdn.net -4- 2005 年 1 月 1 期 总第 2 期
  9. 9. 《CSDN 社区电子杂志——Java 杂志》 真正使用时才从数据库加载。不过,实现这项功能需要首先在编译期对字节码进行增强。 详细的改进列表请看:http://www.hibernate.org/200.html 1.3. JBoss 4 应用服务器指南文档发布 近日,开源组织 JBoss 发布了 J2EE 应用服务器 JBoss 4.0 的应用指南文档。JBoss 用户可以在 以下地址下载这份文档: http://docs.jboss.org/jbossas/jboss4guide/r1/html/ 目前这份文档尚未最终正式定稿,可以在 JBoss 文档论坛提出意见和建议。 JBoss 4.0 是业界领先的开源 J2EE 应用服务器,也是唯一一个全面基于 AOP 思想设计的应用 服务器产品,因此受到 Java 开发者的广泛关注。 http://emag.csdn.net -5- 2005 年 1 月 1 期 总第 2 期
  10. 10. 《CSDN 社区电子杂志——Java 杂志》 业界动态 1.1. IBM 为开源献上免费午餐 无偿开放 500 件专利 IBM 已经决定让开放源代码开发人员放心地使用其 500 件软件专利,这也是 IBM 为鼓励协作 编程思想而采取的最新步骤。 对于象 IBM 这样在研发上投入巨资,获得专利,然后向其它厂商许可专利的公司而言,这是很小 但重要的一步。但是, IBM 在美国取得的 10000 件软件专利中, 在 绝大多数仍然不是“免费午餐”。 Linux 厂商 RedHat 反对软件专利,并免费开放其很少的软件专利。Novell 则表示将利用它的 专利反击针对开放源代码软件的法律行动。IBM 是 Linux 的热心支持者,有数百名软件编程人员 在从事 Linux 的开发工作。它在去年 8 月份表示,决不会利用其专利攻击 Linux。 一些人担心专利可能会伤及 Linux.惠普的一名官员在 2002 年警告称,他预计微软将利用专利 攻击 Linux 和其它开放源代码项目,微软已经开始更多地关注其专利许可计划了。一家开展 Linux 专利保险业务的保险公司称,Linux 侵犯了 283 项专利,其中 60 项为 IBM 所拥有。 专利软件对于 Linux 和其它开放源代码项目而言是破坏性因素。Linux 和其它开放源代码软件 使用的 GPL 许可协议禁止使用专利软件,在开放源代码软件中发现专利软件代码至少将迫使编程 人员编写替代性的代码,客户也需要根据新版本对自己的系统进行必要的改变。 在计算技术领域,IBM 是当之无愧的专利王,它在全球和美国分别获得了 40000 和 25000 件 专利。在 2004 年,美国专利和商标署授予了 IBM3248 项专利,这也使得它连续 12 年成为获得专 利最多的厂商。 IBM 表示,它免费开放的专利覆盖了许多技术,其中包括动态连接操作系统进程、导出文件 的协议、数据库和操作系统之间的互操作性、语言处理、用户界面、互联网。 IBM 将本周二的这一举措称作是在这一方向上迈出的第一步。IBM 的一名代表在周一表示, 未来他们将免费开放更多的软件专利,供开放源代码软件使用。IBM 还计划开放被应用在开放标 准中的专利,这将使这些标准能够更方便地被应用在开放源代码和专有软件中。 IBM 新成立的知识产权部门的负责人柯利在一份声明中表示,他希望其它公司能够效仿 IBM。 他说,通过今天的举措,我们将越来越多地利用专利鼓励和保护全球性的创新,利用开放标准来 鼓励和保护互操作性,我们建议其它厂商也采取类似的行动。我们将继续与美国专利和商标署以 http://emag.csdn.net -6- 2005 年 1 月 1 期 总第 2 期
  11. 11. 《CSDN 社区电子杂志——Java 杂志》 及其它机构合作,确保美国的专利系统能够继续向前发展,解决创新经济的挑战。 1.2. 诺基亚与沃达丰携手 拟制订手机 Java 行业标准 在芬兰埃斯波(Espoo ),诺基亚和沃达丰(VODAFONE)联合宣布了移动服务架构计划, 旨在为移动产业和移动用户带来更多的利益。该计划的目的在于通过定义下一代基于开放标准的 移动 JAVA 服务架构规范,简化移动 JAVA 标准。它将代表并服务于整个移动价值链,包括其他领 先的移动设备制造商、移动运营商和 IT 公司。 该计划将在 Java Community ProcessSM(JCPSM )的范围内制订和行使其标准。八月初, J2ME?执行委员会批准了该项目提交的第一个 JAVA 标准要求(JSRs)。为了保持 JAVA API 服务 架构的一致性,JSRs248 和 249 将包含一些新的 JSRs 元素,并明确一些现有的规范,而不会引入 任何新的 API 规范。 该计划将进一步规范 JSRs 的许可条款,以实现开放、公平和可预见性。因此,诺基亚、沃达 丰将与 SUN 联合制定该计划的许可框架,JSR248 和 249 的技术兼容工具包(TCKs)的开发和许 可将由 SUN 负责。 该计划得到了移动行业巨头的广泛支持,包括 Orange、西门子、索尼爱立信、SUN 和 T-Mobile International. 这些公司都有意加入诺基亚和沃达丰,成为 JAVA 服务架构规范制定专家组的成员。 通过采用此标准,开发商可以开发出能够在 JAVA 手机上轻松互发的软件,这将为移动用户提供丰 富的 JAVA 应用选择。 移动 JAVA 服务架构的管理框架还包括提高安全性的内容。通过实现软件到移动终端的空中发 送和管理,该管理框架将支持先进的远程平台以及面向企业和服务提供商的应用管理。这将降低 移动软件维护的费用。此外,它还为商业用户和消费者提供了在移动终端上获取最新应用和服务 的简易操作。采用该 JAVA 标准的应用平台将为运营商、企业、服务提供商和设备制造商带来新的 商机。 为了制定平台的要求和容量,该计划的目标和职责范围将与一些国际组织保持协调一致,如 OSGI 联盟、开放移动联盟(OMA )、开放移动终端平台(OMTP)和互连网联盟(W3C )。该标 准还将提供 MIDP 环境下的向后平滑兼容。 http://emag.csdn.net -7- 2005 年 1 月 1 期 总第 2 期
  12. 12. 《CSDN 社区电子杂志——Java 杂志》 年度盘点 ——2004 开发技术年度综述之 Java 世界 (天极网) 2004 年 Java 世界发生了巨大变化,主要方面是诞生和发展了几个新名词:IOC 、AOP、SOA、 MDA,当然,除了这些都是决定 Java 技术未来走向的革命性发展以外,还有很多细部和微观的发 展,我们先来谈谈这些重要的细节技术发展。 首先, Java 的根基 JDK 已经跨越到了 J2SE 1.5,或者称为 J2SE 5.0,不过,我更喜欢称它为 1.5,延续性是我们应用程序员更关心的,当然革命性是那些新技术发明者更陶醉的,所以他们曾 经取名 J2SE 2.0,现在,为了表示这种跨越,而且跨越是非常巨大,一下子达到了 J2SE5.0,非常 夸张,不过老外在技术上确实经常极端,"偏执者才能生存"我想是其行动主义文化的主要基础。 J2SE1.5 最吸引眼球的我认为主要是 annotate 特性,该特性可以大大降低程序员的编程量,它 和 Java Relfect 机制结合,可以编制出相当灵活的软件系统或框架。 从 J2SE1.5 看出,SUN 正在试图简化 Java,但是也许这一简化动作来得迟了点。 同样,珊珊来迟的是 J2EE Web 层的一个标准 JSF,JSF 使得程序员在开发 J2EE 的 Web 程序 时,能够如同开发 SWING 那样实现可视化开发,提高了开发效率,但是必须有高级开发工具支持。 由于好东西来得太迟,在一份最近调查中显示,开源项目 Struts 已经在 J2EE 实际 Web 层开发 中占据主导地位,Struts 在 2004 年是达到成熟顶点,它的主要特点是将 Form 表单对象化,同时提 供简单的 XML 标签替代以前 Jsp 中的 Java 语言,这样在 Jsp 中彻底消灭了 Java 代码,除了 Struts, Tapestry 这种彻底抛弃 Jsp 的开源 Web 框架产品也值得一提,它和 WebWork 一起成为一颗引人注 目的星星。 2004 年发生了太多新的激动人心的事情,其中最引人注目的是 AOP 和 SOA 的迅速发展,Java 世界的发展一直以来是分两条路线,第一条是工业路线,以 SUN、IBM、BEA 和 Oracle 等工业巨 头为代表的业界标准,当工业巨头制定出 EJB 2.0 以后,他们认为在 JavaBeans 技术框架内 EJB 已 经走到极限,基本无需太多发展,因此,他们将关注目光投向软件系统服务功能上,当一个个 EJB 组件提供了可重用的功能后,如何向不同客户输出这些强大的、可重用的功能呢?是反复安装拷 贝这些组件功能?还是以一种服务的方式适时提供全面的租用?SOA 面向服务架构因此提出来, http://emag.csdn.net -8- 2005 年 1 月 1 期 总第 2 期
  13. 13. 《CSDN 社区电子杂志——Java 杂志》 并且得到工业界巨头的大量投入和发展,同时,他们还在关注流程的可定制化和可视化开发,通 过强大的开发平台,可以很轻松地完成工作流的业务定制和修改。 当业界巨头关注重点从 JavaBeans 结构转移时,一种新的设计思想和编程风格 AOP(面向方 面编程)诞生了,面向方面编程是 OOP 面向对象编程的延续,AOP 于 2003 年底已经在国外热起 来,到了 2004 年应该算是全面开花,各种 AOP 产品如 JBoss 4.0、Spring、Aspectwerkz 等迅速诞 生和发展,带给程序员全新的概念和理念冲击,AOP 编程方法可以应用在软件开发的各个领域, 当你发现某个功能具有普遍性和通用性以后,那么这个功能也许可以使用 AOP 实现,这样你的代 码优雅,同时可维护性和拓展性大大增强。 Ioc 反转控制应该说有着 AOP 类似解耦思路,通过 Ioc 模式或容器,可以比较彻底分离 JavaBeans 之间的调用和被调用关系,达到真正地面向接口编程,是 Ioc 使的面向接口编程变得更 具有意义而且重要,Ioc 的产品如纯洁的 PicoContainer 以及 Spring 等等。 开源和业界标准的分歧不仅仅体现在 JavaBeans 体系发展上,还体现在对象持久化方式上,在 2004 年有三种流行的对象持久化在被广泛使用:EJB 的 CMP、Hibernate 和 JDO,这三者之间的区 别和联系也是很多程序员津津乐道的,特别是 Hibernate 的创始人 Gavin King 不断对 JDO 的质疑, 使的 Hibernate 名气大升,也使的 JDO 一直未能够进入 EJB 的持久化标准,Spring+Hibernate 架构 以及使用基于 JBoss 的 EJB 架构成为低成本高质量 J2EE 流行架构。 这种"混乱"的局面下,EJB 3.0 标准 Preview 方案被 2004 年 Java ONE 大会首次提出,EJB 3.0 试图取悦那些轻量方案的追随者,同时又能兼顾过去 EJB 标准的系列发展,JBoss 迅速地提供了对 EJB3.0 支持包,其中我们看到了 Gavin King 这位斗士的身影。 同时,Hibernate 向何处去是我们应用系统程序员关心的,Struts 2.0 正在向 JSF 标准靠拢和迁 移,Hibernate 是否能够一直孤军作战?目前一项旨在统一 J2EE 持久层技术的标准方案正在启动 中,我们期望简单统一的持久层方案出台,减少程序员选择迁移之苦。 2004 年又是 Java 世界吵闹的一年,有的程序员说:现在学 java 却越学越糊涂,看了很多东西, 不但大脑里没有头绪,反而有种走火入魔的感觉,因为各种技术派别都在争夺话语权,话语权的 争夺意味着商机的诞生,JBoss 和 Spring 的开发团体先后转为商业公司是一个证明。对于应用者来 说,没有永远的解决方案,只有合适的工具,Java 世界提供给你的是工具箱,而非一种选择,需 求是选择工具的唯一原因。 让我们视野从 J2EE 思想和技术之争转移到需求分析领域的领域,在这个领域一直也存在两种 意见:面向数据表分析还是面向模型分析?也就是说,建立一个新的系统,是先分析设计数据表 http://emag.csdn.net -9- 2005 年 1 月 1 期 总第 2 期
  14. 14. 《CSDN 社区电子杂志——Java 杂志》 还是模型,前者是以前数据库系统经常采取的方式,但是这一传统的方式目前也受到 OO 对象的 冲击,MDA(面向模型分析)在 2004 年成熟开花,各种 Java 成品也如雨后春笋一样遍地开花, MDA 思想提出了极端观点:将来只有建模专家(其它程序员都变成蓝领工人了),只要建模专家 通过 UML 设计出一个系统的模型,通过特定的 Java MDA 工具就可自动生成相应的代码,好像真 的不需要普通程序员了。 结束语 总之,2004 年的 Java 技术带给我们更多的是激动和压力,新技术发展以月计算,作为程序员 的我们如何跟上这些新技术发展,同时能够选择正确的技术引入我们自己的应用系统,这些才是 我们的真正挑战。 http://emag.csdn.net - 10 - 2005 年 1 月 1 期 总第 2 期
  15. 15. 《CSDN 社区电子杂志——Java 杂志》 技术专题—J2SE 5.0 新特性精解 升级到 J2SE 5 平台的 5 大理由 作者:Calvin Austin,2005 年 1 月 4 日 本文给出了升级到 Java 2 Platform, Standard Edition (J2SE platform) 5.0 的 5 大理由。每个理由 都通过大量数据和参考资料来证实升级到 5.0 版本将大大降低开发与运行成本。 J2SE 5.0(代号 Project Tiger)于 2004 年 9 月底发布。它是 Java 平台多年来的重大更新之一。 Java 社区为其新增功能欢呼不已,然而这些新增功能还无法全面地描述此版本的特色。与以往任 何版本相比,这一平台更能满足高水平的测试要求,更适合于任务关键型产品的开发。 J2SE 5.0 中的改进非常之多,本文选出最重要的前 5 条理由实非易事。我的选择如下: 1.1. 以前的应用程序可以直接在 5.0 上运行 “为了确保向后高度兼容,兼容测试次数是 1.4 版本中的两倍...” ——Calvin Austin Sun Microsystems 现有的应用程序无需重新设计或重新编译就可以直接在 J2SE 5.0 中使用。不仅现有应用程序 的投资得到了保护,而且应用程序实际上已经使用新的 Java 运行时,并从中获益。 为了确保向后高度兼容,兼容测试次数是 1.4 版本中的两倍。这些兼容测试只是 Java 测试套 件的一部分,该测试套件包含近 20 万个测试,其中接受测试的有许多著名的 Java 产品。 既然应用程序可以未加修改地运行,那么 J2SE 5.0 能为您提供什么呢? 1.1.1. 改进的性能 在 J2SE 5.0 中,客户机和服务器应用程序的性能均得到重大的改进,由于性能改进非常明显, 我将它列为第 2 条理由,后面将详述。 1.1.2. 监控和易管理性 J2SE 5.0 引入了先进的监控和易管理性框架,并将其内建在 Java 平台的虚拟机上(Java 虚拟 http://emag.csdn.net - 11 - 2005 年 1 月 1 期 总第 2 期
  16. 16. 《CSDN 社区电子杂志——Java 杂志》 机或 JVM)。您可以使用带有行业标准 JMX 和 SNMP 协议的现有管理控制台来监控 JVM,甚至可 以检测低内存情况。JDK 发行版提供一个名为 Jconsole 的演示。您可以借助它来评估监控 JVM 所 带来的好处,从而了解如何拓展自己的可用性指标。 1.1.3. 新的观感 Java 平台已包含了一个插入式观感(Look-and-Feel)框架。新增的海洋风格的观感允许跨平 台的应用程序能够在海洋和本机操作系统的观感之间进行切换,而无需重建或重新编译。 1.2. 速度更快 从下图可以看出,众多因素让 J2SE 5.0 的系统速度得到了显著提高。 1.2.1. 缩短启动时间 如果您最近几年一直没有启动过 Java 桌面应用程序,您可能会有惊喜的发现。引入了类数据 共享(结合其他流线化选项)后,一些应用程序的启动时间缩短了近 30%。 1.2.2. 卓越的 64 位性能 J2SE 5.0 的 64 位 JVM 可以为 AMD64/Opteron CPU 和 Suse Linux Enterprise Edition 8.0 SLES 提 供记录结果。另外,32 位 JRE 版本可以在同一 64 位操作系统下与现有的 32 位 Web 浏览器同时运 行。 http://emag.csdn.net - 12 - 2005 年 1 月 1 期 总第 2 期
  17. 17. 《CSDN 社区电子杂志——Java 杂志》 1.2.3. 性能改善 现在,JVM 可在服务器级别的机器上自我配置和优化。服务器级别的机器是指具有两个或更 多 CPU,内存至少 2GB 的机器。基于服务器的性能改善消除了那些长时间运行的应用程序所需的 内存和优化类。其结果是不用改动一行代码或提供任何运行时选项,就可以使应用序服务器基准 程序提高 80%的性能! 1.3. 缩短开发时间 集成开发环境(IDE)通过使用自动生成和向导来完成常规任务,从而减轻了开发人员的负担。 J2SE 5.0 新增的语言功能进一步流线化了开发过程,无论您是使用 IDE 还是在文本编辑器手工编 码。 1.3.1. 减少开发人员编码数量 Java 语言的许多改进都减少了开发人员必须编码的数量。下图针对与 J2SE 1.4.2 版本的比较, 对这种减少进行了量化。举一个现实中的例子来说,一个开放源码应用服务器使用了超过 2,000 个 迭代器。通过用新的循环改进功能来取代,编码量大大减少多达 40,000 个字符。对于开发人员来 说,这相当于节省了两个小时的手工编码工作量(按每秒 5 个字符计算)。 图 2:减少的编码工作量(编码行数更少) J2SE 5.0 平台增加了 metadata,通过使用工具生成样板文件代码和配置信息,大大短少了开发 http://emag.csdn.net - 13 - 2005 年 1 月 1 期 总第 2 期
  18. 18. 《CSDN 社区电子杂志——Java 杂志》 时间。在 JSR 181 定义的 SOA 和 Web 服务的情况下,开发人员通过自动生成公共代码,有望减少 50%的编码工作量。[注意:上图给出的例子表明,元数据 JAX-RPC 从 209 字符减少至 95 字符, 使用 generics 的循环改进从 139 字符减少至 100 字符,不使用 generic 的循环改进从 121 字符减至 90 字符,自动装箱从 69 字符减至 56 字符]。 元数据将减少编写部署描述文件的工作量。曾有人建议 EJB 3.0 默认由应用程序自身生成配置 信息,从而无需部署描述文件。 1.3.2. 增强的错误检验存储 用 google 搜索“ClassCastException”和“help”关键词将得到 40,000 条搜索结果。Sun 论坛 上的专业搜索报告了 3,444 个开发者案例,他们都是请求帮助跟踪由于类转换异常问题而引起的无 法解释的运行时故障。 在 3,444 个案例中,有 470 个涉及到 pre-generics vector 类。从投资回报的角度来看,在业务 高峰期间任何运行时错误都可能损失公司站点 10%的定单收入(若收入为 30 亿 GBP,则损失 3 亿 GBP)。这还未计入人力和商誉等其他因素。 随着编译时类型安全 generic 类型引入到 Java 平台,通过提醒开发人员在开发期间内是否存在 类型匹配问题,将会降低运行时错误的风险。在论坛的 470 个案例中,Vector 和其他 JDK 中的关 键类库都已使用 J2SE 5.0 中的 generics 进行更新,从而避免重复出现那些无法解释的运行时问题。 1.4. 适用于任务关键型系统 5.0 版本提供了增强的可伸缩性、质量与部署支持。 1.4.1. 可伸缩性 Java 平台的设计令客户机和服务器均具有可伸缩性。 版本引入了一个功能强大的并发类库, 5.0 令多线程编程比从前更简单同时功能也更强大。Java 平台还支持 64 位以及多核心和超线程芯片技 术。64 位 JVM 允许应用程序使用 4 GB 以上的堆空间,还允许与其他 64 位应用程序集成。 1.4.2. 质量 J2SE 5.0 平台已经在一组广泛的系统和操作系统变体上进行了深入的测试。测试中使用了许多 http://emag.csdn.net - 14 - 2005 年 1 月 1 期 总第 2 期
  19. 19. 《CSDN 社区电子杂志——Java 杂志》 流行的应用服务器和客户应用程序。最后一项测试标准——平均故障压力测试时间——以没有任 何故障而完满结束。 1.4.3. 部署 在 J2SE 5.0 之前,很难确定 JVM 产品的事务吞吐量。新的分析工具和自动调优功能提供了更 好的产品合理精简信息和配置。当应用程序投入使用后,可以看到通过这些功能缩减的范围令人 惊叹。 如前在第 1 条理由中重点强调的,为了完成部署过程,JVM 现在能够使用行业标准工具执行 完整的远程监控。这就使得系统管理员无论在集群中还是在传统垂直伸缩的环境中,都可成功地 管理 JVM。所部署应用程序的健康状态和可利用性都能得到监控。 除了上面升级的 4 条技术理由之外,还有最后一条至关重要的理由。 1.5. 您选择了一家优秀的公司 J2SE 5.0 的改进归功于 Java 社区。J2SE 5.0 专家组包括以下 Java 领域的公司:Apache,Apple, BEA Systems,Borland,Cisco Systems,Fujitsu,Hewlett-Packard,IBM,Macromedia,Nokia,Oracle, SAP,SAS Institute,SavaJe Technologies,Sun Microsystems,John Zukowski,Osvaldo Doederlein 和 Juergen Kreileder。 共有 16 个由著名 Java 领域专家组成的工作组。它们组织了全世界 160 名专家协同工作,最终 形成了 J2SE 5.0 Java 规范。该规范覆盖了从语言更新到并发类库再到类压缩文件 API。有关更多 的技术细节,请参阅 J2SE 5.0 in a Nutshell。也可参考本页侧栏给出的参考书,诸如此类的参考书 正在不断增加。 1.5.1. 有关 J2SE 5.0 的图书 Java 5.0 Tiger: A Developer's Notebook. David Flanagan, Brett McLaughlin. O'Reilly & Associates, 2004. Java 2 v5.0 (Tiger) New Features. Herbert Schildt. McGraw-Hill Osborne Media, 2004. Beginning Java 2, JDK 5 Edition. Ivor Horton. Wiley, 2004. Core Java 2, Volume I, II (7th Ed.). Cay Horstmann, Gary Cornell. Pearson Prentice Hall, 2005. http://emag.csdn.net - 15 - 2005 年 1 月 1 期 总第 2 期
  20. 20. 《CSDN 社区电子杂志——Java 杂志》 Just Java 2 (6th Ed.). Peter van der Linden. Prentice Hall, 2004. An Introduction to Programming and Object-Oriented Design Using Java 2, 2nd Ed. Jaime Niño, Frederick A. Hosch. Wiley 2005 The Java Class Libraries Poster : Java 2 Platform Standard Edition 5.0 (8th Ed.). Patrick Chan, Rosanna Lee. Addison-Wesley Professional, 2005. Objects, Abstraction, Data Structures and Design Using Java Version 5.0. Elliot Koffman, Paul Wolfgang. Wiley, 2004. 1.6. 结束语 本文列出了我使用 Java 2 Platform, Standard Edition (J2SE platform) 5.0 的 5 个重要理由。 (本文 不涵盖客户机或服务器端的全部功能)。有关平台的所有资料,从规范到源代码,均可从 SCSL 和 Java Research Library 获得,它有助于您作出自己的决策。请通过社区论坛联系我们,让我们分享 您对 J2SE 5.0 版本的看法。 下面的工具和应用程序利用了 J2SE 5.0 增强功能,从而提高开发人员的效率。 New J2SE 5.0 Enhanced tools and applications Java System Application Server 9 NetBeans 4.0 Eclipse 3.x Borland JBuilder 2005 - Wily Introscope http://emag.csdn.net - 16 - 2005 年 1 月 1 期 总第 2 期
  21. 21. 《CSDN 社区电子杂志——Java 杂志》 Tiger 核心库简介 本文作者: 大阿福 (toafu2002@yahoo.com.cn ) 摘要:Java 之所以得到很多程序员的青睐,除了她的严谨的面向对象特性外,还有一个不容 轻视的因素,那就是她强大的类库。一门语言如果没有库,功能将会大打折扣,在 JDK5.0 版本中, 其核心库也有了诸多的改进,本文将就其新特性进行简介。 1.1. 事务的属性 1.1.1. 访问环境变量 虽然 Java 从一开始推出的时候,就一再强调她的跨平台特性,“一次编译,到处运行”。所以 能够访问平台专有信息的 System.getenv()方法从一开始进入 java 的 lang 包时,就遭到了大多数人 的反对。虽然 1.0 版本中抛弃了其中的一些内容,但是在 tiger 版本中我们又可以使用这个方法了, 请注意该方法的名称全部是小写。 使用的方法很简单:如清单 1 public class EnvTest { public static void main(String args[]) { System.out.println(System.getenv(args[0])); } } 只要给定变量的名称,就可以得到它的当前值。 Tiger 提供了两个版本的 getenv(),第二个版本返回系统当前设置中所有的环境变量对应的 “名值”对。清单 2 说明该方法的使用: import java.util.Map; public class EnvDump { public static void main(String args[]) { for (Map.Entry entry: System.getenv().entrySet()) { System.out.println(entry.getKey() + “/” + entry.getValue()); } } } http://emag.csdn.net - 17 - 2005 年 1 月 1 期 总第 2 期
  22. 22. 《CSDN 社区电子杂志——Java 杂志》 1.1.2. 访问子进程 J2SE平台的前期版本提供了Runtime类的exec()方法用来创建子进程的运行,在Tiger版本中, 这个方法依然有效,但是为了更方便的定制子进程,Tiger提供了ProcessBuilder类,它使依据改变 了的进程变量来创建子进程更加便利。ProcessBuilder提供了directory(File)方法来改变进程的工作目 录,用enviroment()方法在进程空间中添加和删除环境变量。清单 3 说明了Processor的简单用法, 它使用 ipconfig 命令获得 Internet 配置信息。该方法适用于多数平台,否则可以将 ipconfig 改写成所用平台上的工作命令。启动进程构造程序之后,需要获得其 InputStream,以读入所创 建进程的结果。 import java.io.*; public class ProcessTest { public static void main(String args[]) throws IOException { Process p = new ProcessBuilder("ipconfig").start(); InputStream is = p.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while ((line = br.readLine()) != null) { System.out.println(line); } } } 运行结果如清单 4: Windows 2000 IP Configuration Ethernet adapter 本地连接: Connection-specific DNS Suffix . : IP Address. . . . . . . . . . . . : 10.97.69.166 Subnet Mask . . . . . . . . . . . : 255.255.255.128 Default Gateway . . . . . . . . . : 10.97.69.129 ProcessBuilder 类不仅能生成新的进程,而且还能获得其结果。在调用其 start() 方法之前, 还可以调整进程所执行的上下文。如果不喜欢环境变量,可以使用 environment 获得当前设置, 并调用 clear() 清除映射。如果需要添加环境变量,可以调用 environment 获得当前设置, 然 后 通 过 put(name, value) 添 加 新 的 变 量 。 如 果 希 望 使 用 新 的 工 作 目 录 , 可 以 调 用 directory() 并提供新的工作目录作为 File 对象。就是这么简单。 使用表示将运行的命令及其参数的数目可变的字符串参数来创建 ProcessBuilder,一旦使 http://emag.csdn.net - 18 - 2005 年 1 月 1 期 总第 2 期
  23. 23. 《CSDN 社区电子杂志——Java 杂志》 用新的环境变量和工作目录配置 ProcessBuilder,就可以调用 start() 来执行命令。 1.2. 并发集合 Java 中的集合框架一直是令人津津乐道的,在 Tiger 中,集合框架新添加了 Queue 接口以及这 个接口的并发和非并发实现,以及并发 Map 的实现和专用于读操作大大超过写操作的情况下的并 发 List 和 Set 实现。 1.2.1. Queue 接口 虽然在 List 的两端可以添加删除元素达到模拟 queue 的性能,但是 Queue 的提出提供了支持 添加、删除和检查集合的更为方便的方法:如清单 5 所示 public boolean offer(Object element) public Object remove() public Object poll() public Object element() public Object peek() 一些队列有大小长度的限制,因此如果想在一个已满的队列中加入一个新项,多出的项就会 被拒绝。这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。remove() 和 poll() 方法都是从队列中删除第 一个元素(head) remove() 的行为与 Collection 接口的版本相似,但是新的 poll() 方法 。 在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。 后两个方法 element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在 队列为空时,element() 抛出一个异常,而 peek() 返回 null。 1.2.1.1. 基本队列实现 1、 在 Tiger 中,java.util.LinkedList 已经被改造为实现了 java.util.List 和 java.util.Queue 两个接口。 清单 6 显示的是 LinkedList 的简单使用: Queue queue = new LinkedList(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); System.out.println("Head of queue is: " + queue.poll()); http://emag.csdn.net - 19 - 2005 年 1 月 1 期 总第 2 期
  24. 24. 《CSDN 社区电子杂志——Java 杂志》 输出的结果应该是 One 2、 util 包新增加的 AbstractQueue 类,其工作方式类似于 AbstractList 和 AbstractSet 类,在需要创 建自己所需的对垒时,可以直接继承该类,必须实现 offer(),poll(),peek()三个方法,读者可 以在其中提供优化的实现。读者也可以不必创建自己的子类,而是使用几个 tiger 提供的实现, 其中两个时不阻塞队列:PriorityQueue 和 ConcurrentLinkedQueue。PriorityQueue 类实际上是维 护了一个有序的队列,加入到该 Queue 中的元素按照它们的自然顺序来进行排序,排序的依据 是元素对 java.util.Comparable 的实现或者传递给该 Queue 构造函数的 Comparator 参数。如果 将清单 6 的具体实现改为 PriorityQueue,则输入的结果应该为 Four,因为按字母顺序排列,Four 是排在了第一个。ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不 需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以不需要知道队列的大小, ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息 会很慢,需要遍历队列。 1.2.1.2. 阻塞队列实现 Tiger 提供的 java.util.concurrent 包在 集合框架 中加入了 BlockingQueue 接口和五个阻塞队 列类。简单的讲,阻塞队列的意思就是当队列无空间时,添加元素的线程执行操作阻塞,直到有 空间;或者是,当队列为空无元素可删时,执行删除的线程阻塞,知道有元素可删。BlockingQueue 接口的 Javadoc 给出了阻塞队列的基本用法,如清单 7 所示。生产者中的 put() 操作会在没有空 间可用时阻塞,而消费者的 take() 操作会在队列中没有任何东西时阻塞。 class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while(true) { queue.put(produce()); } } catch (InterruptedException ex) { ... handle ...} } Object produce() { ... } } class Consumer implements Runnable { private final BlockingQueue queue; Consumer(BlockingQueue q) { queue = q; } public void run() { http://emag.csdn.net - 20 - 2005 年 1 月 1 期 总第 2 期
  25. 25. 《CSDN 社区电子杂志——Java 杂志》 try { while(true) { consume(queue.take()); } } catch (InterruptedException ex) { ... handle ...} } void consume(Object x) { ... } } class Setup { void main() { BlockingQueue q = new SomeQueueImplementation(); Producer p = new Producer(q); Consumer c1 = new Consumer(q); Consumer c2 = new Consumer(q); new Thread(p).start(); new Thread(c1).start(); new Thread(c2).start(); } } 另外五个阻塞队列提供的情况各有不同: • ArrayBlockingQueue:一个由数组支持的有界队列。 • LinkedBlockingQueue:一个由链接节点支持的可选有界队列。 • PriorityBlockingQueue:一个由优先级堆支持的无界优先级队列。 • DelayQueue:一个由优先级堆支持的、基于时间的调度队列。 • SynchronousQueue:一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制 前两个类 ArrayBlockingQueue 和 LinkedBlockingQueue 几乎相同,只是在底层存储实现方面 有所不同,LinkedBlockingQueue 并不总是有容量界限。无大小界限的 LinkedBlockingQueue 类在 添加元素时永远不会有阻塞队列的等待(至少在其中有 Integer.MAX_VALUE 元素之前不会,这 个时候采用的容量限制即是 Integer.MAX_VALUE)。 PriorityBlockingQueue 是具有无界限容量的队列,它利用所包含元素的 Comparable 排序顺序 来以逻辑顺序维护元素。可以将它看作 TreeSet 的可能替代物。例如,在队列中加入字符串 One、 Two、Three 和 Four 会导致 Four 被第一个取出来。对于没有天然顺序的元素,可以为构造函数 提供一个 Comparator 。不过对 PriorityBlockingQueue 使用时需要注意,从 iterator() 返回的 Iterator 实例并不一定按照优先级顺序返回元素。如果必须以优先级顺序遍历所有元素,那么让它 们都通过 toArray() 方法并自己对它们排序,像 Arrays.sort(pq.toArray())。 新的 DelayQueue 实现可能是其中最有意思(也是最复杂)的一个。加入到队列中的元素必 http://emag.csdn.net - 21 - 2005 年 1 月 1 期 总第 2 期
  26. 26. 《CSDN 社区电子杂志——Java 杂志》 须实现新的 Delayed 接口(只有一个方法 —— long getDelay(java.util.concurrent.TimeUnit unit))。 因为队列的大小没有界限,使得添加可以立即返回,但是在延迟时间过去之前,不能从队列中取 出元素。如果多个元素完成了延迟,那么最早失效/失效时间最长的元素将第一个取出。实际上没 有听上去这样复杂。清单 8 演示了这种新的阻塞队列集合的使用: import java.util.*; import java.util.concurrent.*; public class Delay { /** * Delayed implementation that actually delays */ static class NanoDelay implements Delayed { long trigger; NanoDelay(long i) { trigger = System.nanoTime() + i; } public int compareTo(Object y) { long i = trigger; long j = ((NanoDelay)y).trigger; if (i < j) return -1; if (i > j) return 1; return 0; } public boolean equals(Object other) { return ((NanoDelay)other).trigger == trigger; } public boolean equals(NanoDelay other) { return other.trigger == trigger; } public long getDelay(TimeUnit unit) { long n = trigger - System.nanoTime(); return unit.convert(n, TimeUnit.NANOSECONDS); } public long getTriggerTime() { return trigger; } public String toString() { return String.valueOf(trigger); } } public static void main(String args[]) throws InterruptedException { http://emag.csdn.net - 22 - 2005 年 1 月 1 期 总第 2 期
  27. 27. 《CSDN 社区电子杂志——Java 杂志》 Random random = new Random(); DelayQueue queue = new DelayQueue(); for (int i=0; i < 5; i++) { queue.add(new NanoDelay(random.nextInt(1000))); } long last = 0; for (int i=0; i < 5; i++) { NanoDelay delay = (NanoDelay)(queue.take()); long tt = delay.getTriggerTime(); System.out.println("Trigger time: " + tt); if (i != 0) { System.out.println("Delta: " + (tt - last)); } last = tt; } } } 这个例子首先是一个内部类 NanoDelay,它实质上将暂停给定的任意纳秒(nanosecond)数, 这里利用了 System 的新 nanoTime() 方法。然后 main() 方法只是将 NanoDelay 对象放到队列中 并再次将它们取出来。如果希望队列项做一些其他事情,就需要在 Delayed 对象的实现中加入方 法,并在从队列中取出后调用这个新方法。(请随意扩展 NanoDelay 以试验加入其他方法做一些 有趣的事情。 )显示从队列中取出元素的两次调用之间的时间差。如果时间差是负数,可以视为一 个错误,因为永远不会在延迟时间结束后,在一个更早的触发时间从队列中取得项。 SynchronousQueue 类是最简单的。它没有内部容量。它就像线程之间的手递手机制。在队列 中加入一个元素的生产者会等待另一个线程的消费者。当这个消费者出现时,这个元素就直接在 消费者和生产者之间传递,永远不会加入到阻塞队列中 1.2.2. ConcurrentMap 实现 新的 java.util.concurrent.ConcurrentMap 接口和 ConcurrentHashMap 实现只能在键不存在时 将元素加入到 map 中,只有在键存在并映射到特定值时才能从 map 中删除一个元素。 ConcurrentMap 中有一个新的 putIfAbsent() 方法用于在 map 中进行添加。这个方法以要添加 到 ConcurrentMap 实现中的键和值为参数,就像普通的 put() 方法,但是只有在 map 不包含这 个键时,才能将键加入到 map 中。如果 map 已经包含这个键,那么这个键的现有值就会返回。 http://emag.csdn.net - 23 - 2005 年 1 月 1 期 总第 2 期
  28. 28. 《CSDN 社区电子杂志——Java 杂志》 这个操作等于清单 9 的代码: if (!map.containsKey(key)) return map.put(key, value); else return map.get(key); 像 putIfAbsent() 方法一样,重载后的 remove() 方法有两个参数 —— 键和值。在调用时, 只有当键映射到指定的值时才从 map 中删除这个键。如果不匹配,那么就不删除这个键,并返回 false。如果值匹配键的当前映射内容,那么就删除这个键。清单 10 显示了这种操作的等价源代码: if (map.get(key).equals(value)) { map.remove(key); return true; } else { return false; } 1.2.3. CopyOnWriteArrayList 和 CopyOnWriteArraySet copy-on-write 模式是这样声明的,为了维护对象的一致性快照,要依靠不可变性(immutability) 来消除在协调读取不同的但是相关的属性时需要的同步。对于集合,这意味着如果有大量的读(即 get()) 和迭代,不必同步操作以照顾偶尔的写(即 add())调用。对于新的 CopyOnWriteArrayList 和 CopyOnWriteArraySet 类,所有可变的(mutable)操作都首先取得后台数组的副本,对副本进 行更改,然后替换副本。这种做法保证了在遍历自身更改的集合时,永远不会抛出 ConcurrentModificationException。遍历集合会用原来的集合完成,而在以后的操作中使用更新后的 集合。 这些新的集合,CopyOnWriteArrayList 和 CopyOnWriteArraySet,最适合于读操作通常大大超 过写操作的情况。一个最常提到的例子是使用监听器列表。已经说过,Swing 组件还没有改为使 用新的集合。相反,它们继续使用 javax.swing.event.EventListenerList 来维护它们的监听器列表。 如清单 11 所示,集合的使用与它们的非 copy-on-write 替代物完全一样。只是创建集合并在 其中加入或者删除元素。即使对象加入到了集合中,原来的 Iterator 也可以进行,继续遍历原来 集合中的项。 import java.util.*; http://emag.csdn.net - 24 - 2005 年 1 月 1 期 总第 2 期
  29. 29. 《CSDN 社区电子杂志——Java 杂志》 import java.util.concurrent.*; public class CopyOnWrite { public static void main(String args[]) { List list1 = new CopyOnWriteArrayList(Arrays.asList(args)); List list2 = new ArrayList(Arrays.asList(args)); Iterator itor1 = list1.iterator(); Iterator itor2 = list2.iterator(); list1.add("New"); list2.add("New"); try { printAll(itor1); } catch (ConcurrentModificationException e) { System.err.println("Shouldn't get here"); } try { printAll(itor2); } catch (ConcurrentModificationException e) { System.err.println("Will get here."); } } private static void printAll(Iterator itor) { while (itor.hasNext()) { System.out.println(itor.next()); } } } 这个示例程序用命令行参数创建 CopyOnWriteArrayList 和 ArrayList 这两个实例。在得到每 一个实例的 Iterator 后 , 分 别 在 其 中 加 入 一 个 元 素 。 当 ArrayList 迭 代 因 一 个 ConcurrentModificationException 问题而立即停止时,CopyOnWriteArrayList 迭代可以继续,不会 抛出异常,因为原来的集合是在得到 iterator 之后改变的。如果这种行为(比如通知原来一组事件 监听器中的所有元素)是您需要的,那么最好使用 copy-on-write 集合。如果不使用的话,就还用 原来的,并保证在出现异常时对它进行处理。 1.3. Formatter 对于那些从一开始就使用 Java 编程而从没有接触过 C 的人,或者,对那些对 C 没有足够 了解的人,格式化字符串是一些古怪的文本串,它们指定一组变量的输出特性。不是用加号将字 http://emag.csdn.net - 25 - 2005 年 1 月 1 期 总第 2 期
  30. 30. 《CSDN 社区电子杂志——Java 杂志》 符串连接在一起(如 firstName + " " + lastName),而是提供一个字符串描述输出,并提供参数以 在方法调用结束时,替换字符串中的占位符:String s = String.format("%1$s %2$s", firstName, lastName)。 首先,让我们分析新的 java.util.Formatter 类。您可能不会经常直接使用这个类,但是它提供 了所要进行的格式化的内部机制。在这个类的 Javadoc 中,会看到一个描述所支持的格式化选项 的表。这些选项的范围从以类似 %7.4f 这样的格式指定浮点数的精度和位数,到格式化时间的 %tT,到格式化第三个参数 %3$s。 用 Formatter 格式化输出分为两步:创建一个 Appendable 对象以存储输出,用 format() 方 法将带格式的内容放到这个对象中。下面列出了 Appendable 接口的实现器: • BufferedWriter • CharArrayWriter • CharBuffer • FileWriter • FilterWriter • LogStream • OutputStreamWriter • PipedWriter • PrintStream • PrintWriter • StringBuffer • StringBuilder • StringWriter • Writer 在使用 Formatter 类时,可以将实现了这个接口的对象传递给构造函数 Formatter 以把它作为 目标。大多数这种类看起来很相似,除了 StringBuilder 类。StringBuilder 与 StringBuffer 类几乎 相同,只有一个大的区别:它不是线程安全的。如果知道要在单线程中构建字符串,就使用 StringBuilder。如果构建过程会跨越多个线程,则使用 StringBuffer。清单 12 显示了通常如何开始 使用 Formatter: StringBuilder sb = new StringBuilder(); Formatter formatter = new Formatter(sb, Locale.US); 创建了 Formatter 类后,用格式化字符串和参数调用其 format() 方法。如果需要使用与传递 http://emag.csdn.net - 26 - 2005 年 1 月 1 期 总第 2 期
  31. 31. 《CSDN 社区电子杂志——Java 杂志》 给出构造函数的不同的 Locale 作为格式化输出的一部分,还可以向 format() 方法传递一个 Locale 对象。清单 13 显示了两种不同的 format(): public Formatter format(String format, Object... args) public Formatter format(Locale l, String format, Object... args) 如果希望得到精度为 10 位数字的 Pi 值,清单 14 中的代码会将这个值放到 StringBuilder 中并打印输出。打印 formatter 对象将显示 Appendable 对象的内容。 import java.util.Locale; import java.util.Formatter; public class Build { public static void main(String args[]) { StringBuilder sb = new StringBuilder(); Formatter formatter = new Formatter(sb, Locale.US); formatter.format("PI = %12.10f", Math.PI); System.out.println(formatter); } } 1.3.1. PrintStream 支持 PrintStream 类 中 定 义 了 常 见 的 、 分 别 用 于 写 入 标 准 输 出 和 标 准 错 误 的 System.out 和 System.err 对象。Tiger 引入了两个新的构造函数(用于直接写入文件)和六个方法以提供对格式 化 的 支 持 ( 三 对 ) 第 一 对 是 另 一 版 本 的 append() 方 法 。 这 一 对 方 法 实 现 了 新 的 。 java.lang.Appendable 接口。一般不会直接调用这些方法。直接调用的是 format() 和 printf(),其 中 printf() 版本只是 format() 版本的方便的包装器,如清单 15 所示: public PrintStream format(String format, Object... args) public PrintStream format(Locale l, String format, Object... args) 要记住新的变量参数支持,它是由 ... 指派的 清单 16 演示了用 PrintStream 的 format() 方法打印今天的日期: http://emag.csdn.net - 27 - 2005 年 1 月 1 期 总第 2 期
  32. 32. 《CSDN 社区电子杂志——Java 杂志》 import java.util.Calendar; public class Now { public static void main(String args[]) { System.out.format("Today is %1$tB %1$te, %1$tY.",Calendar.getInstance()); } } 运行这个程序的输出是 Today is January 19, 2005.,当然实际的输出取决于运行这个程序的日 期。上面代码中的格式化字符串 %1$tB 告诉程序使用第一个参数并打印 date 对象的完整月名。 格式化字符串 %1$te 意味着显示月中的日期,而格式化字符串 %1$tY 是四位数字的年。在 Formatter 对象的 Javadoc 中列出了打印日期的其他选项。 1.3.2. String 支持 String 类有两个新的 static format() 方法,它们的作用与相应的 printf() 类似。发送一个格式 化字符串和参数(还可能有 Locale) 、并使用在格式化字符串中指定的格式转换参数。如果是这个 方法的 String 版本,那么是以 String 对象而不是经过流返回结果。这些方法不是很显眼,但是有 了它们就可以避免直接使用 Formatter 对象并创建中间的 StringBuilder。 1.3.3. 格式化任意对象 到目前为止看到的每项内容都是描述如何使用新的格式化能力对已有对象和基本数据进行格 式化。如果希望用 Formatter 提供对自己的对象的支持,那么就要用到 Formattable 接口。通过在 自己的类中实现如清单 17 所示的一个 formatTo() 方法,可以对自已的类使用格式化字符串: void formatTo(Formatter formatter, int flags, Integer width, Integer precision) 清单 18 演示了通过提供一个具有 name 属性的简单类来使用 Formattable 接口。这个 name 显示在输出中,它支持控制输出的宽度和对齐。 import java.util.Locale; import java.util.Formatter; http://emag.csdn.net - 28 - 2005 年 1 月 1 期 总第 2 期
  33. 33. 《CSDN 社区电子杂志——Java 杂志》 import java.util.Formattable; public class MyObject implements Formattable { String name; public MyObject(String name) { this.name = name; } public void formatTo( Formatter fmt, int f, Integer width, Integer precision) { StringBuilder sb = new StringBuilder(); if (precision == null) { // no max width sb.append(name); } else if (name.length() < precision) { sb.append(name); } else { sb.append(name.substring(0, precision - 1)).append('*'); } // apply width and justification if ((width != null) && (sb.length() < width)) { for (int i = 0, n=sb.length(); i < width - n; i++) { if ((f & Formattable.LEFT_JUSTIFY) == Formattable.LEFT_JUSTIFY) { sb.append(' '); } else { sb.insert(0, ' '); } } } fmt.format(sb.toString()); } public static void main(String args[]) { MyObject my1 = new MyObject("John"); MyObject my2 = new MyObject("Really Long Name"); // First / Using toString() System.out.println("First Object : " + my1); // Second / Using Formatter System.out.format("First Object : '%s'n", my1); // Second / Using Formatter System.out.format("Second Object: '%s'n", my2); http://emag.csdn.net - 29 - 2005 年 1 月 1 期 总第 2 期
  34. 34. 《CSDN 社区电子杂志——Java 杂志》 // Second / Using Formatter with width System.out.format("Second Object: '%10.5s'n", my2); // Second / Using Formatter with width and left justification System.out.format("Second Object: '%-10.5s'n", my2); } } 运行这个程序会生成如清单 19 所示的输出。前两行展示了使用 toString 和 Formatter 的不同 结果。后三行显示宽度和对齐控制的选项。 First Object : MyObject@10b62c9 First Object : 'John' Second Object: 'Really Long Name' Second Object: ' Real*' Second Object: 'Real* 1.4. 从 XML 文件中装载属性 Properties 这个类对于读者来说应该并不陌生,在应用程序的配置文件中大多采用的都是这样 的属性文本文件。在 Tiger 中,java.util.Properties 类现在提供了一种为程序装载和存储设置的更容 易的方法:loadFromXML(InputStream is) 和 storeToXML(OutputStream os, String comment) 方法。 1.4.1. XML 属性文件 XML 属性文件的指定 DTD 如清单 20 所示: <?xml version="1.0" encoding="UTF-8"?> <!-- DTD for properties --> <!ELEMENT properties ( comment?, entry* ) > <!ATTLIST properties version CDATA #FIXED "1.0"> <!ELEMENT comment (#PCDATA) > <!ELEMENT entry (#PCDATA) > <!ATTLIST entry key CDATA #REQUIRED> 简单的 XML 属性文件如清单 21 所示: <?xml version="1.0" encoding="UTF-8"?> http://emag.csdn.net - 30 - 2005 年 1 月 1 期 总第 2 期
  35. 35. 《CSDN 社区电子杂志——Java 杂志》 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>Hi</comment> <entry key="foo">bar</entry> <entry key="fu">baz</entry> </properties> 相信读者对此一目了然。 1.4.2. 存取 XML 属性文件 1.4.2.1. 读取 XML 属性文件 读取 XML 版本的 Properties 文件与读取老格式的文件没什么不同。如清单 22 所示 import java.util.*; import java.io.*; public class LoadSampleXML { public static void main(String args[]) throws Exception { Properties prop = new Properties(); FileInputStream fis = new FileInputStream("sampleprops.xml"); prop.loadFromXML(fis); prop.list(System.out); System.out.println("nThe foo property: " + prop.getProperty("foo")); } } 1.4.2.2. 保存 XML 属性文件 用新的 storeToXML() 方法创建 xml 文件。只要传递一个 OutputStream 和一个用于注释的 String 就可以了。代码如清单 23 所示: import java.util.*; import java.io.*; public class StoreXML { public static void main(String args[]) throws Exception { Properties prop = new Properties(); http://emag.csdn.net - 31 - 2005 年 1 月 1 期 总第 2 期
  36. 36. 《CSDN 社区电子杂志——Java 杂志》 prop.setProperty("one-two", "buckle my shoe"); prop.setProperty("three-four", "shut the door"); prop.setProperty("five-six", "pick up sticks"); prop.setProperty("seven-eight", "lay them straight"); prop.setProperty("nine-ten", "a big, fat hen"); FileOutputStream fos = new FileOutputStream("rhyme.xml"); prop.storeToXML(fos, "Rhyme"); fos.close(); } } 运行结果如清单 24 所示: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>Rhyme</comment> <entry key="seven-eight">lay them straight</entry> <entry key="five-six">pick up sticks</entry> <entry key="nine-ten">a big, fat hen</entry> <entry key="three-four">shut the door</entry> <entry key="one-two">buckle my shoe</entry> </properties> 1.5. 其他核心库的增强 另外,Tiger 以下核心库方面也有了一定的增强,由于篇幅所限,这里就不一一赘述了,请感 兴趣的读者参照 JDK 5.0 API Documentation 中的相关内容。 1.5.1. Scanner java.util.Scanner 类可用于将文本转换成原语或字符串。由于它是基于 java.util.regex 包的, 因此它也提供了一种方式来管理正则表达式,该表达式把搜索建立在流、文件数据、字符串或 Readable 接口的封装行为(implementor)上。 1.5.2. JavaBeans 组件体系结构 已经添加了一个称为 IndexedPropertyChangeEvent 的 PropertyChangeEvent 子类来支持界限 http://emag.csdn.net - 32 - 2005 年 1 月 1 期 总第 2 期
  37. 37. 《CSDN 社区电子杂志——Java 杂志》 属性,该属性使用索引来指出 bean 的更改部分。另外,已经在 PropertyChangeSupport 类中添加 了一些方法,用以支持激发索引属性改变事件。 1.5.3. Math 包 java.math 包包含了下面的增强功能: • BigDecimal 类已经为固定精度浮点计算添加了支持。参见 JSR 13. • Math 和 StrictMath 库包含双曲线超越函数(sinh、cosh 和 tanh) 、立方根和基于 10 的 对数等。 • 十六进制浮点数支持 —— 为允许特定浮点值的精确和可预知的说明,十六进制表示法可 用于浮点数的字面值,以及用于 Float 和 Double 中浮点数转换方法的字符串。 1.5.4. 网络 1.5.5. 安全性 这一版本的 J2SE 在安全方面大大增强了。它为安全性令牌提供了更好的支持, 为更多的安 全标准(SASL、OCSP 和 TSP)提供了支持,改进了可伸缩性(SSLEngine)和性能,此外在 Crypto 和 Java GSS 方面也提供了许多增强功能。有关更多信息,请参见上面的链接。 1.5.6. 国际化 增强功能有: • 现在 字符处理是以 4.0 版本的 Unicode 标准为基础的。这就影响了 java.lang 包中的 Character 类和 String 类、java.text 包中的排序规则和双向文本分析功能、 java.util.regex 包中的 Character 类及 J2SE 的其他许多部分。作为这一升级的一部 分,JSR 204 专家组已经指定了对辅助字符的支持,而且在整个 J2SE 中已经实现了该支 持。有关更多信息,请参见 JSR 204 或 Character 类文档。 • DecimalFormat 类已经得到了增强,现在可以格式化和解析 BigDecimal 和 BigInteger 值,而不会丢失精确度。这些值的格式化是自动得到增强的;必须启用 setParseBigDecimal 方法才可以进行到 BigDecimal 的解析。 • 现在,Vietnamese 在 java.util 和 java.text 包中所有的 Locale 敏感功能方面得到了支持。有 关支持的 Locale 和写系统的完整信息,请参见 支持的 Locale。 http://emag.csdn.net - 33 - 2005 年 1 月 1 期 总第 2 期
  38. 38. 《CSDN 社区电子杂志——Java 杂志》 1.5.7. 序列化 已经添加了支持来处理 1.5 版本中新增的枚举类型。序列化一个枚举实例的规定不同于序列 化一个“普通”可序列化对象的那些规则:枚举实例的序列化表单只包括它的枚举常量名和指出它的 基本枚举类型的信息。反序列化行为也是不同的 —— 类信息用于查找相应的枚举类,并且为了 获取返回的枚举常量,通过使用那个类和接收的常量名来调用 Enum.valueOf 方法。 1.6. 结束语 以上所讲到的只是 J2SE 1.5 核心库新特性的一小部分,还有很多其他新特性限于篇幅不能一 一 讲 述 , 有 兴 趣 进 一 步 详 细 了 解 这 些 新 特 性 的 读 者 可 以 参 看 http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html 可获取更多信息。 Tiger“通过增强 Java 平台的力量、允许开发者更容易地使用,Java 编程语言的这些改进将吸 引大量各种 Java 开发者”,是“Java 技术发展历程的一个重要里程碑”。 http://emag.csdn.net - 34 - 2005 年 1 月 1 期 总第 2 期
  39. 39. 《CSDN 社区电子杂志——Java 杂志》 JAVA 泛型 QUIK START JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为 5.0。这说明 JAVA 已经有大幅 度的变化.本文将讲解 JDK5.0 支持的新功能-----JAVA 的泛型. 1.1. JAVA 泛型 其实 JAVA 的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样 的 method(String str1,String str2 ),方法中参数 str1、str2 的值是可变的。而泛型也是一样的,这样写 class Java_Generics<K,V>,这里边的 K 和 V 就象方法中的参数 str1 和 str2,也是可变。下面看看例 子: //code list 1 import java.util.Hashtable; class TestGen0<K,V>{ public Hashtable<K,V> h=new Hashtable<K,V>(); public void put(K k, V v) { h.put(k,v); } public V get(K k) { return h.get(k); } public static void main(String args[]){ TestGen0<String,String> t=new TestGen0<String,String>(); t.put("key", "value"); String s=t.get("key"); System.out.println(s); } } 正确输出:value 这只是个例子(JAVA中集合框架都泛型化了,这里费了 2 遍事☺),不过看看是不是创建一个 用类型作为参数的类,参数是K,V,传入的“值”是String类型。这个类他没有特定的待处理型 别,以前我们定义好了一个类,在输入输入参数有所固定,是什么型别的有要求,但是现在编写 程序,完全可以不制定参数的类型,具体用的时候来确定,增加了程序的通用性,像是一个模板。 呵呵,类似C++的模板(类似)。 http://emag.csdn.net - 35 - 2005 年 1 月 1 期 总第 2 期
  40. 40. 《CSDN 社区电子杂志——Java 杂志》 1.1.1. 泛型通配符 下面我们先看看这些程序: //Code list 2 void TestGen0Medthod1(List l) { for (Object o : l) System.out.println(o); } 看看这个方法有没有异议,这个方法会通过编译的,假如你传入 String,就是这样 List<String>。 接着我们调用它,问题就出现了,我们将一个 List<String>当作 List 传给了方法,JVM 会给我们一 个警告,说这个破坏了类型安全,因为从 List 中返回的都是 Object 类型的,而让我们再看看下面 的方法。 //Code list 3 void TestGen0Medthod1(List<String> l) { for (Object o : l) System.out.println(o); } 因为这里的 List<String>不是 List<Object>的子类,不是 String 与 Object 的关系,就是说 List<String>不隶属于 list<Object>,他们不是继承关系,所以是不行的,这里的 extends 是表示限制 的。 类型通配符是很神奇的,List<?>这个你能为他做什么呢?怎么都是“?”,它似乎不确定,他 总不能返回一个?作为类型的数据吧,是啊他是不会返回一个“?”来问程序员的?JVM 会做简 单的思考的,看看代码吧,更直观些。 //code list 4 List<String> l1 = new ArrayList<String>(); li.add(“String”); List<?> l2 = l1; System.out.println(l1.get(0)); 这段代码没问题的,l1.get(0)将返回一个 Object。 1.1.2. 编写泛型类要注意: 1、 在定义一个泛型类的时候,在 “<>”之间定义形式类型参数,例如: “class TestGen<K, V>”,其中“K” , “V”不代表值,而是表示类型。 2、 实例化泛型对象的时候,一定要在类名后面指定类型参数的值(类型),一共要有两次 http://emag.csdn.net - 36 - 2005 年 1 月 1 期 总第 2 期
  41. 41. 《CSDN 社区电子杂志——Java 杂志》 书写。例如:TestGen<String,String> t=new TestGen<String,String>(); 3、 泛型中<K extends Object>,extends 并不代表继承,它是类型范围限制。 1.2. 泛型与数据类型转换 1.2.1. 消除类型转换 上面的例子大家看到什么了,数据类型转换的代码不见了。在以前我们经常要书写以下代码, 如: //code list 5 import java.util.Hashtable; class Test { public static void main(String[] args) { Hashtable h = new Hashtable(); h.put("key", "value"); String s = (String)h.get("key"); System.out.println(s); } } 这个我们做了类型转换,是不是感觉很烦的,并且强制类型转换会带来潜在的危险,系统可 能会抛一个 ClassCastException 异常信息。在 JDK5.0 中我们完全可以这么做,如: //code list 6 import java.util.Hashtable; class Test { public static void main(String[] args) { Hashtable<String,Integer> h = new Hashtable<String,Integer> (); h.put("key", new Integer(123)); int s = h.get("key").intValue(); System.out.println(s); } } 这里我们使用泛化版本的 HashMap,这样就不用我们来编写类型转换的代码了,类型转换的过 程交给编译器来处理,是不是很方便,而且很安全。上面是 String 映射到 String,也可以将 Integer 映射为 String,只要写成 HashTable<Integer,String> h=new HashTable<Integer,String>();h.get(new Integer(0))返回 value。果然很方便。 http://emag.csdn.net - 37 - 2005 年 1 月 1 期 总第 2 期
  42. 42. 《CSDN 社区电子杂志——Java 杂志》 1.2.2. 自动解包装与自动包装的功能 从上面有没有看到有点别扭啊,h.get(new Integer(123))这里的 new Integer(123);好烦的,在 JDK5.0 之前我们只能忍着了,现在这种问题已经解决了,请看下面这个方法。我们传入一个 int 这一基本型别,然后再将 i 的值直接添加到 List 中,其实 List 是不能储存基本型别的,List 中应该 存储对象,这里编译器将 int 包装成 Integer,然后添加到 List 中去。接着我们用 List.get(0);来检索 数据,并返回对象再将对象解包装成 int。恩,JDK5.0 给我们带来更多方便与安全。 //Code list 7 public void autoBoxingUnboxing(int i) { ArrayList<Integer> L= new ArrayList<Integer>(); L.add(i); int a = L.get(0); System.out.println("The value of i is " + a); } 1.2.3. 限制泛型中类型参数的范围 也许你已经发现在 code list 1 中的 TestGen<K,V>这个泛型类,其中 K,V 可以是任意的型别。也 许你有时候呢想限定一下 K 和 V 当然范围,怎么做呢?看看如下的代码: //Code list 8 class TestGen2<K extents String,V extends Number> { private V v=null; private K k=null; public void setV(V v){ this.v=v; } public V getV(){ return this.v; } public void setK(K k){ this.k=k; } public V getK(){ return this.k; } public static void main(String[] args) { http://emag.csdn.net - 38 - 2005 年 1 月 1 期 总第 2 期
  43. 43. 《CSDN 社区电子杂志——Java 杂志》 TestGen2<String,Integer> t2=new TestGen2<String,Integer>(); t2.setK(new String("String")); t2.setV(new Integer(123)); System.out.println(t2.getK()); System.out.println(t2.getV()); } } 上边 K 的范围是<=String ,V 的范围是<=Number,注意是“<=”,对于 K 可以是 String 的, V 当然也可以是 Number,也可以是 Integer,Float,Double,Byte 等。看看下图也许能直观些 图-1 A A1 A2 A2 1 A2 2 请看上图 A 是上图类中的基类, A2 分别是 A 的子类, 有 2 个子类分别是 A2_1, A1, A2 A2_2。 然后我们定义一个受限的泛型类 class MyGen<E extends A2>,这个泛型的范围就是上图中兰色部 分。 这个是单一的限制,你也可以对型别多重限制,如下: class C<T extends Comparable<? super T> & Serializable> 我们来分析以下这句, extends Comparable 这个是对上限的限制, T Comparable<? super T>这个是下限的限制,Serializable 是第 2 个上限。一个指定的类型参数可以具有一个或多个 上限。具有多重限制的类型参数可以用于访问它的每个限制的方法和域。 1.2.4. 多态方法 //Code list 9 class TestGen { <T extends Object> public static List<T> make(T first) { return new List<T>(first); } } http://emag.csdn.net - 39 - 2005 年 1 月 1 期 总第 2 期
  44. 44. 《CSDN 社区电子杂志——Java 杂志》 J2SE 5.0 专题 之 用户接口 1.1. 引子 “从 Java 诞生至今已有 9 年时间,而从第二代 Java 平台 J2SE 算起也有 5 个年头了。在这样 的背景下,将下一个版本的版本号从 1.5 改为 5.0 可以更好的反映出新版 J2SE 的成熟度、稳定性、 可伸缩性和安全性。 Sun 公司如是解释 Java 的这次意义深远的变革。众所周知 Sun 公司从发布 ” Java 以来,对 Java 的每一次变更可谓是小心翼翼,特别是经历了版本一到版本二的变更后,Java 一直就停留在比较稳定的时期,这对于一个处于 IT 行业剀1

×