在线试读

get_product_contenthtml

部分
走近Java
第1章 走近Java

第1章 走近Java
世界上并没有完美的程序,但我们并不因此而沮丧,因为写程序本来就是一个不断追求完美的过程。
1.1 概述
Java不仅仅是一门编程语言,还是一个由一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于嵌入式系统、移动终端、企业服务器、大型机等各种场合,如图1-1所示。时至今日,Java技术体系已经吸引了900多万软件开发者,这是全球的软件开发团队。使用Java的设备多达几十亿台,其中包括11亿多台个人计算机、30亿部移动电话及其他手持设备、数量众多的智能卡,以及大量机顶盒、导航系统和其他设备。
Java能获得如此广泛的认可,除了它拥有一门结构严谨、面向对象的编程语言之外,还有许多不可忽视的优点:它摆脱了硬件平台的束缚,实现了“一次编写,到处运行”的理想;它提供了一个相对安全的内存管理和访问机制,避免了绝大部分的内存泄露和指针越界问题;它实现了热点代码检测和运行时编译及优化,这使得Java应用能随着运行时间的增加而获得更高的性能;它有一套完善的应用程序接口,还有无数来自商业机构和开源社区的第三方类库来帮助它实现各种各样的功能……Java所带来的这些好处使程序的开发效率得到了很大的提升。作为一名Java程序员,在编写程序时除了尽情发挥Java的各种优势外,还应该去了解和思考一下Java技术体系中这些技术特性是如何实现的。认识这些技术运作的本质,是自己思考“程序这样写好不好”的基础和前提。当我们在使用一种技术时,如果不再依赖书本和他人就能得到这些问题的答案,那才算上升到了“不惑”的境界。
本书将与读者一起分析Java技术中重要的那些特性的实现原理。在本章中,我们将重点介绍Java技术体系内容以及Java的历史、现在和未来的发展趋势。
1.2 Java技术体系
从广义上讲,Clojure、JRuby、Groovy等运行于Java虚拟机上的语言及其相关的程序都属于Java技术体系中的一员。如果仅从传统意义上来看,Sun官方所定义的Java技术体系包括以下几个组成部分:
?Java程序设计语言
?各种硬件平台上的Java虚拟机
?Class文件格式
?Java API类库
?来自商业机构和开源社区的第三方Java类库
我们可以把Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK(Java DevelopmentKit),JDK是用于支持Java程序开发的小环境,在后面的内容中,为了讲解方便,有一些地方会以JDK来代替整个Java技术体系。另外,可以把JavaAPI类库中的Java SE API子集和Java虚拟机这两部分统称为JRE(Java RuntimeEnvironment),JRE是支持Java程序运行的标准环境。图1-2展示了Java技术体系所包含的内容,以及JDK和JRE所涵盖的范围。
以上是根据各个组成部分的功能来进行划分的,如果按照技术所服务的领域来划分,或者说按照Java技术关注的重点业务领域来划分,Java技术体系可以分为4个平台,分别为:
?Java Card:支持一些Java小程序(Applets)运行在小内存设备(如智能卡)上的平台。
?Java ME(Micro Edition):支持Java程序运行在移动终端(手机、PDA)上的平台,对JavaAPI有所精简,并加入了针对移动终端的支持,这个版本以前称为J2ME。
?Java SE(StandardEdition):支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API,这个版本以前称为J2SE。
?Java EE(EnterpriseEdition):支持使用多层架构的企业应用(如ERP、CRM应用)的Java平台,除了提供Java SEAPI外,还对其做了大量的扩充并提供了相关的部署支持,这个版本以前称为J2EE。
1.3 Java发展史
从个Java版本诞生到现在已经有18年的时间了。沧海桑田一瞬间,转眼18年过去了,在图1-3所展示的时间线中,我们看到JDK已经发展到了1.7版。在这18年里还诞生了无数和Java相关的产品、技术和标准。现在让我们走入时间隧道,从孕育Java语言的时代开始,再来回顾一下Java的发展轨迹和历史变迁。
1991年4月,由James Gosling博士领导的绿色计划(GreenProject)开始启动,此计划的目的是开发一种能够在各种消费性电子产品(如机顶盒、冰箱、收音机等)上运行的程序架构。这个计划的产品就是Java语言的前身:Oak(橡树)。Oak当时在消费品市场上并不算成功,但随着1995年互联网潮流的兴起,Oak迅速找到了适合自己发展的市场定位并蜕变成为Java语言。
1995年5月23日,Oak语言改名为Java,并且在SunWorld大会上正式发布Java1.0版本。Java语言次提出了“Write Once,Run Anywhere”的口号。
1996年1月23日,JDK 1.0发布,Java语言有了个正式版本的运行环境。JDK1.0提供了一个纯解释执行的Java虚拟机实现(Sun Classic VM)。JDK1.0版本的代表技术包括:Java虚拟机、Applet、AWT等。
1996年4月,10个主要的操作系统供应商申明将在其产品中嵌入Java技术。同年9月,已有大约8.3万个网页应用了Java技术来制作。在1996年5月底,Sun公司于美国旧金山举行了首届JavaOne大会,从此JavaOne成为全世界数百万Java语言开发者每年一度的技术盛会。
1997年2月19日,Sun公司发布了JDK 1.1,Java技术的一些基础的支撑点(如JDBC等)都是在JDK1.1版本中发布的,JDK1.1版的技术代表有:JAR文件格式、JDBC、JavaBeans、RMI。Java语法也有了一定的发展,如内部类(InnerClass)和反射(Reflection)都是在这个时候出现的。
直到1999年4月8日,JDK1.1一共发布了1.1.0~1.1.8九个版本。从1.1.4之后,每个JDK版本都有一个自己的名字(工程代号),分别为:JDK1.1.4 - Sparkler(宝石)、JDK 1.1.5 - Pumpkin(南瓜)、JDK 1.1.6 -Abigail(阿比盖尔,女子名)、JDK 1.1.7 - Brutus(布鲁图,古罗马政治家和将军)和JDK 1.1.8 Chelsea(切尔西,城市名)。
1998年12月4日,JDK迎来了一个里程碑式的版本JDK1.2,工程代号为Playground(竞技场),Sun在这个版本中把Java技术体系拆分为3个方向,分别是面向桌面应用开发的J2SE(Java2 Platform, Standard Edition)、面向企业级开发的J2EE(Java 2 Platform,Enterprise Edition)和面向手机等移动终端开发的J2ME(Java 2 Platform, MicroEdition)。在这个版本中出现的代表性技术非常多,如EJB、Java Plug-in、JavaIDL、Swing等,并且这个版本中Java虚拟机次内置了JIT(Just In Time)编译器(JDK1.2中曾并存过3个虚拟机,Classic VM、HotSpot VM和Exact VM,其中ExactVM只在Solaris平台出现过;后面两个虚拟机都是内置JIT编译器的,而之前版本所带的ClassicVM只能以外挂的形式使用JIT编译器)。在语言和API级别上,Java添加了strictfp关键字与现在Java编码之中极为常用的一系列Collections集合类。在1999年3月和7月,分别有JDK1.2.1和JDK 1.2.2两个小版本发布。
1999年4月27日,HotSpot虚拟机发布,HotSpot初由一家名为“LongviewTechnologies”的小公司开发,因为HotSpot的优异表现,这家公司在1997年被Sun公司收购了。HotSpot虚拟机发布时是作为JDK1.2的附加程序提供的,后来它成为了JDK 1.3及之后所有版本的Sun JDK的默认虚拟机。
2000年5月8日,工程代号为Kestrel(美洲红隼)的JDK 1.3发布,JDK 1.3相对于JDK1.2的改进主要表现在一些类库上(如数学运算和新的Timer API等),JNDI服务从JDK1.3开始被作为一项平台级服务提供(以前JNDI仅仅是一项扩展),使用CORBAIIOP来实现RMI的通信协议,等等。这个版本还对Java 2D做了很多改进,提供了大量新的Java 2DAPI,并且新添加了JavaSound类库。JDK 1.3有1个修正版本JDK1.3.1,工程代号为Ladybird(瓢虫),于2001年5月17日发布。
自从JDK1.3开始,Sun维持了一个习惯:大约每隔两年发布一个JDK的主版本,以动物命名,期间发布的各个修正版本则以昆虫作为工程名称。
2002年2月13日,JDK 1.4发布,工程代号为Merlin(灰背隼)。JDK1.4是Java真正走向成熟的一个版本,Compaq、Fujitsu、SAS、Symbian、IBM等著名公司都有参与甚至实现自己独立的JDK1.4。哪怕是在十多年后的今天,仍然有许多主流应用(Spring、Hibernate、Struts等)能直接运行在JDK1.4之上,或者继续发布能运行在JDK 1.4上的版本。JDK1.4同样发布了很多新的技术特性,如正则表达式、异常链、NIO、日志类、XML解析器和XSLT转换器等。JDK1.4有两个后续修正版:2002年9月16日发布的工程代号为Grasshopper(蚱蜢)的JDK1.4.1与2003年6月26日发布的工程代号为Mantis(螳螂)的JDK 1.4.2。
2002年前后还发生了一件与Java没有直接关系,但事实上对Java的发展进程影响很大的事件,那就是微软公司的.NETFramework发布了。这个无论是技术实现上还是目标用户上都与Java有很多相近之处的技术平台给Java带来了很多讨论、比较和竞争,.NET平台和Java平台之间声势浩大的孰优孰劣的论战到目前为止都在继续。
2004年9月30日,JDK 1.5发布,工程代号Tiger(老虎)。从JDK1.2以来,Java在语法层面上的变换一直很小,而JDK1.5在Java语法易用性上做出了非常大的改进。例如,自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环(foreach循环)等语法特性都是在JDK1.5中加入的。在虚拟机和API层面上,这个版本改进了Java的内存模型(Java MemoryModel,JMM)、提供了java.util.concurrent并发包等。另外,JDK 1.5是官方声明可以支持Windows9x平台的后一个JDK版本。
2006年12月11日,JDK 1.6发布,工程代号Mustang(野马)。在这个版本中,Sun终结了从JDK1.2开始已经有8年历史的J2EE、J2SE、J2ME的命名方式,启用Java SE 6、Java EE 6、Java ME6的命名方式。JDK 1.6的改进包括:提供动态语言支持(通过内置Mozilla JavaScriptRhino引擎实现)、提供编译API和微型HTTP服务器API等。同时,这个版本对Java虚拟机内部做了大量改进,包括锁与同步、垃圾收集、类加载等方面的算法都有相当多的改动。
在2006年11月13日的JavaOne大会上,Sun公司宣布终会将Java开源,并在随后的一年多时间内,陆续将JDK的各个部分在GPLv2(GNU General Public Licensev2)协议下公开了源码,并建立了OpenJDK组织对这些源码进行独立管理。除了极少量的产权代码(EncumberedCode,这部分代码大多是Sun本身也无权限进行开源处理的)外,OpenJDK几乎包括了SunJDK的全部代码,OpenJDK的质量主管曾经表示,在JDK 1.7中,SunJDK和OpenJDK除了代码文件头的版权注释之外,代码基本上完全一样,所以OpenJDK 7与Sun JDK1.7本质上就是同一套代码库开发的产品。
JDK1.6发布以后,由于代码复杂性的增加、JDK开源、开发JavaFX、经济危机及Sun收购案等原因,Sun在JDK发展以外的事情上耗费了很多资源,JDK的更新没有再维持两年发布一个主版本的发展速度。JDK1.6到目前为止一共发布了37个Update版本,的版本为Java SE 6 Update37,于2012年10月16日发布。
2009年2月19日,工程代号为Dolphin(海豚)的JDK 1.7完成了其个里程碑版本。根据JDK1.7的功能规划,一共设置了10个里程碑。后一个里程碑版本原计划于2010年9月9日结束,但由于各种原因,JDK1.7终无法按计划完成。
从JDK1.7开始的功能规划来看,它本应是一个包含许多重要改进的JDK版本,其中的Lambda项目(Lambda表达式、函数式编程)、Jigsaw项目(虚拟机模块化支持)、动态语言支持、GarbageFirst收集器和Coin项目(语言细节进化)等子项目对于Java业界都会产生深远的影响。在JDK1.7开发期间,Sun公司由于相继在技术竞争和商业竞争中都陷入泥潭,公司的股票市值跌至仅有高峰时期的3%,已无力推动JDK1.7的研发工作按正常计划进行。为了尽快结束JDK1.7长期“跳票”的问题,Oracle公司收购Sun公司后不久便宣布将实行“B计划”,大幅裁剪了JDK 1.7预定目标,以便保证JDK1.7的正式版能够于2011年7月28日准时发布。“B计划”把不能按时完成的Lambda项目、Jigsaw项目和Coin项目的部分改进延迟到JDK1.8之中。终,JDK1.7的主要改进包括:提供新的G1收集器(G1在发布时依然处于Experimental状态,直至2012年4月的Update4中才正式“转正”)、加强对非Java语言的调用支持(JSR-292,这项特性到目前为止依然没有完全实现定型)、升级类加载架构等。
到目前为止,JDK 1.7已经发布了9个Update版本,的Java SE 7 Update9于2012年10月16日发布。从Java SE 7 Update 4起,Oracle开始支持Mac OSX操作系统,并在Update 6中达到完全支持的程度,同时,在Update6中还对ARM指令集架构提供了支持。至此,官方提供的JDK可以运行于Windows(不含Windows9x)、Linux、Solaris和Mac OS平台上,支持ARM、x86、x64和Sparc指令集架构类型。
2009年4月20日,Oracle公司宣布正式以74亿美元的价格收购Sun公司,Java商标从此正式归Oracle所有(Java语言本身并不属于哪间公司所有,它由JCP组织进行管理,尽管JCP主要是由Sun公司或者说Oracle公司所领导的)。由于此前Oracle公司已经收购了另外一家大型的中间件企业BEA公司,在完成对Sun公司的收购之后,Oracle公司分别从BEA和Sun中取得了目前三大商业虚拟机的其中两个:JRockit和HotSpot,Oracle公司宣布在未来1~2年的时间内,将把这两个优秀的虚拟机互相取长补短,终合二为一。可以预见在不久的将来,Java虚拟机技术将会产生相当巨大的变化。
根据Oracle官方提供的信息,JDK 1.8的个正式版本将于2013年9月发布,JDK 1.8将会提供在JDK1.7中规划过,但终未能在JDK1.7中发布的特性,即Lambda表达式、Jigsaw(很不幸,随后Oracle公司又宣布Jigsaw在JDK1.8中依然无法完成,需要延至JDK 1.9)和JDK 1.7中未实现的一部分Coin等。
在2011年的JavaOne大会上,Oracle公司还提到了JDK1.9的长远规划,希望未来的Java虚拟机能够管理数以GB计的Java堆,能够更高效地与本地代码集成,并且令Java虚拟机运行时尽可能少人工干预,能够自动调节。
1.4 Java虚拟机发展史
上一节我们从整个Java技术的角度观察了Java技术的发展,许多Java程序员都会潜意识地把它与Sun公司的HotSpot虚拟机等同看待,也许还有一些程序员会注意到BEAJRockit和IBM J9,但对JVM的认识不仅仅只有这些。
从1996年初Sun公司发布的JDK 1.0中所包含的Sun ClassicVM到今天,曾经涌现、湮灭过许多或经典或优秀或有特色的虚拟机实现,在这一节中,我们先暂且把代码与技术放下,一起来回顾一下Java虚拟机家族的发展轨迹和历史变迁。
1.4.1 Sun Classic / Exact VM
以今天的视角来看,Sun ClassicVM的技术可能很原始,这款虚拟机的使命也早已终结。但仅凭它“世界上款商用Java虚拟机”的头衔,就足够有让历史记住它的理由。
1996年1月23日,Sun公司发布JDK1.0,Java语言首次拥有了商用的正式运行环境,这个JDK中所带的虚拟机就是ClassicVM。这款虚拟机只能使用纯解释器方式来执行Java代码,如果要使用JIT编译器,就必须进行外挂。但是假如外挂了JIT编译器,JIT编译器就完全接管了虚拟机的执行系统,解释器便不再工作了。用户在这款虚拟机上执行java-version命令,将会看到类似下面这行输出:
java version "1.2.2"
Classic VM (build JDK-1.2.2-001, green threads, sunwjit)
其中的“sunwjit”就是Sun提供的外挂编译器,其他类似的外挂编译器还有SymantecJIT和shuJIT等。由于解释器和编译器不能配合工作,这就意味着如果要使用编译器执行,编译器就不得不对每一个方法、每一行代码都进行编译,而无论它们执行的频率是否具有编译的价值。基于程序响应时间的压力,这些编译器根本不敢应用编译耗时稍高的优化技术,因此这个阶段的虚拟机即使用了JIT编译器输出本地代码,执行效率也和传统的C/C 程序有很大差距,“Java语言很慢”的形象就是在这时候开始在用户心中树立起来的