| | 网站首页 | 政策法规 | 天文航天 | 地理人文 | 文学历史 | 科学生活 | 信息军事 | 卫生保健 | 奇妙自然 | 留言 | | |
![]() |
|
| 您现在的位置: 活到老学到老 >> 信息军事 >> 数据编程 >> 正文 |
|
|||||
| J2SE 5.0专题之语言特性(一) | |||||
作者:未知 文章来源:转载 点击数: 更新时间:2006-2-28 ![]() |
|||||
|
【IT168 编程开发】1.1背景 J2SE(TM) 5.0正式发布至今已超过3个月的时间了,就在前不久,大概是在两周之前,Sun又发布了更新过的JDK 5.0 Update 1,改掉了一些第一个版本中出现的bug。 由于Java社群等待这一从1.4向5.0版本升级已经有相当长的一段时间,大家都很关心5.0中有哪些值得关注的变化,于是blog的相关信息满天飞,我也兴冲冲地在自己的blog中添上了一系列的文章。无奈这些blog文章,包括我自己的在内,通常都是泛泛而谈,因此CSDN第二期Java电子杂志的编辑们计划做一个专题对这一话题与相关人士进行一番深入的探讨。 作为这期电子刊物的一部分,编辑们也邀请我更系统的探讨一下:J2SE(TM) 5.0中新引入的语言特性究竟在实际中有哪些用途,以及为什么要引入这些新特性。对此我深感荣幸。我本人很乐意将我的一些也许算得上经验的Java经验跟大家分享,希望这一篇小文能对大家了解J2SE(TM) 5.0有一定帮助。 1.2. 准备工作 首先,为了了解J2SE(TM) 5.0的新的语言特性,你需要下载新版的JDK,在这里可以找到下载链接:http://java.sun.com/j2se/1.5.0/download.jsp。当然,如果你已经有过手动配置Java环境的经历,我也建议你使用一个支持J2SE(TM) 5.0的IDE,推荐Eclipse SDK 3.1 M4,或者NetBeans IDE 4.0。两个都是开源免费的,且很容易找到(Eclipse不用说了,NetBeans IDE 4.0有与JDK 5.0 Update 1的捆绑版)。 说点题外话,Java的版本号自从1.2开始,似乎就多少显得有点蹩脚。从1.2版本开始,Java (J2SE)被称作Java 2,而不是Java 1.2,现在则显得更加离奇:Java(TM) 2 Platform Standard Edition 5.0或者J2SE(TM) 5.0,而内部的版本号还是1.5.0。那么到底是1、2、还是5呢?来看看Sun官方网站是怎么说的: 从Java诞生至今已有9年时间,而从第二代Java平台J2SE算起也有5个年头了。在这样的背景下,将下一个版本的版本号从1.5改为5.0可以更好的反映出新版J2SE的成熟度、稳定性、可伸缩性和安全性。 好吧,现在我们将面对如下一些名称,而它们指的基本上是同一个东西: l Tiger 如果你对Java各个版本的代号感兴趣,就像这里的"Tiger",可以参考如下网址:http://java.sun.com/j2se/codenames.html。透露一点:Java下一个版本(6.0)的代号是"Mustang"野马,再下一个版本(7.0)的代号是"Dolphin"海豚。 1.3. 概述 J2SE(TM) 5.0引入了很多激进的语言元素变化,这些变化或多或少减轻了我们开发人员的一些编码负担,其中的大部分也必然会被应用到即将发布的J2EE(TM) 5.0中。主要的新特性包括: l 泛型 l C风格的格式化输出 1.4. 泛型 泛型这个题目相当大,大到完全可以就这个话题写一本书。有关Java是否需要泛型和如何实现泛型的讨论也早就在Java社群广为流传。终于,我们在J2SE(TM) 5.0中看到了它。也许目前Java对泛型的支持还算不上足够理想,但这一特性的添加也经足以让我们欣喜一阵了。 在接下来的介绍中,我们会了解到:Java的泛型虽然跟C++的泛型看上去十分相似,但其实有着相当大的区别,有些细节的东西也相当复杂(至少很多地方会跟我们的直觉背道而驰)。可以这样说,泛型的引入在很大程度上增加了Java语言的复杂度,对初学者尤其是个挑战。下面我们将一点一点往里挖。 首先我们来看一个简单的使用泛型类的例子: ArrayList<Integer> aList = new ArrayList<Integer>(); 泛型的使用从这个例子看也是相当易懂。我们在定义ArrayList时,通过类名后面的<>括号中的值指定这个ArrayList接受的对象类型。在编译的时候,这个ArrayList会被处理成只接受该类或其子类的对象,于是任何试图将其他类型的对象添加进来的语句都会被编译器拒绝。 那么泛型是怎样定义的呢?看看下面这一段示例代码:(其中用E代替在实际中将会使用的类名,当然你也可以使用别的名称,习惯上在这里使用大写的E,表示Collection的元素。) public class TestGenerics<E> { 接下来我们更进一步:既然ArrayList<? extends SomeClass>是一个通配的公用父类,那么我们可不可以往声明为ArrayList<? extends SomeClass>的ArrayList实例中添加一个SomeExtendedClass1的对象呢?答案是不能。甚至你不能添加任何对象。为什么?因为ArrayList<? extends SomeClass>实际上代表了所有ArrayList<SomeClass>、ArrayList<SomeExtendedClass1>和ArrayList<SomeExtendedClass2>三种ArrayList,甚至包括未知的接受SomeClass其他子类对象的ArrayList。我们拿到一个定义为ArrayList<? extends SomeClass>的ArrayList的时候,我们并不能确定这个ArrayList具体是使用哪个类作为参数定义的,因此编译器也无法让这段代码编译通过。举例来讲,如果我们想往这个ArrayList中放一个SomeExtendedClass2的对象,我们如何保证它实际上不是其他的如ArrayList<SomeExtendedClass1>,而就是这个ArrayList<SomeExtendedClass2>呢?(还记得吗?ArrayList<Integer>并非ArrayList<Object>的子类。)怎么办?我们需要使用泛型方法。泛型方法的定义类似下面的例子: public static <T extends SomeClass> void add (Collection<T> c, T elem) { Java泛型的最大特点在于它是在语言级别实现的,区别于C# 2.0中的CLR级别。这样的做法使得JRE可以不必做大的调整,缺点是无法支持一些运行时的类型甄别。一旦编译,它就被写死了,能提供的动态能力相当弱。 个人认为泛型是这次J2SE(TM) 5.0中引入的最重要的语言元素,给Java语言带来的影响也是最大。举个例子来讲,我们可以看到,几乎所有的Collections API都被更新成支持泛型的版本。这样做带来的好处是显而易见的,那就是减少代码重复(不需要提供多个版本的某一个类或者接口以支持不同类的对象)以及增强代码的健壮性(编译期的类型安全检查)。不过如何才能真正利用好这个特性,尤其是如何实现自己的泛型接口或类供他人使用,就并非那么显而易见了。让我们一起在使用中慢慢积累。 1.5. 增强的for循环 你是否已经厌倦了每次写for循环时都要写上那些机械的代码,尤其当你需要遍历数组或者Collection,如:(假设在Collection中储存的对象是String类型的) public void showAll (Collection c) { public void showAll (Collection c) { public void showAll (Collection<String> cs) { 对于这个看上去相当方便的新语言元素,当你需要在循环体中访问游标的时候,会显得很别扭:比方说,当我们处理一个链表,需要更新其中某一个元素,或者删除某个元素等等。这个时候,你无法在循环体内获得你需要的游标信息,于是需要回退到原先的做法。不过,有了泛型和增强的for循环,我们在大多数情况下已经不用去操心那些烦人的for循环的表达式和嵌套了。毕竟,我们大部分时间都不会需要去了解游标的具体位置,我们只需要遍历数组或Collection,对吧? 1.6. 自动装箱/自动拆箱 所谓装箱,就是把值类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int型包装成Integer类的对象,或者把double包装成Double,等等。所谓拆箱,就是跟装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为值类型的数据。 在J2SE(TM) 5.0发布之前,我们只能手工的处理装箱和拆箱。也许你会问,为什么需要装箱和拆箱?比方说当我们试图将一个值类型的数据添加到一个Collection中时,就需要先把它装箱,因为Collection的add()方法只接受对象;而当我们需要在稍后将这条数据取出来,而又希望使用它对应的值类型进行操作时,我们又需要将它拆箱成值类型的版本。现在,编译器可以帮我们自动地完成这些必要的步骤。下面的代码我提供两个版本的装箱和拆箱,一个版本使用手工的方式,另一个版本则把这些显而易见的代码交给编译器去完成: public static void manualBoxingUnboxing(int i) { 当然,你需要足够重视的是:一方面,对于值类型和引用类型,在资源的占用上有相当大的区别;另一方面,装箱和拆箱会带来额外的开销。在使用这一方便特性的同时,请不要忘记了背后隐藏的这些也许会影响性能的因素。 |
|||||
| 文章录入:wswys 责任编辑:wswys | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| 双击无法打开硬盘 双击打不开… 无法显示隐藏文件解决方法 Ping同一个域名得到不同IP是… 为何本地网卡会收发异常 如何下载网上的Flash动画 怎么用IE快速访问FTP站点 局域网内复制文件出错怎么办 如何限制外网访问内网 网络已通收发数据为何为零? 为何点击超链接没有反应 |
网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | | |
![]() |
『活到老学到老』 版权所有
|