- Java从入门到精通(第4版)
- 宁跃飞 史卫亚 张洪超编著
- 7207字
- 2022-04-26 18:14:03
0.2 Java简史——带给我们的一点思考
著名人类学家费孝通先生曾指出,我们所谓的“当前”,其实包含着从“过去”历史中拔萃出来的投影和时间选择的积累。历史对于我们来说,并不是什么可有可无的点缀之饰物,而是实用的、不可或缺的前行之基础。
Java从诞生(1995年)发展到现在,已经过去了20多年。了解Java的一些发展历史,有助于我们更好地认识Java,看清这纷杂的编程语言世界,进而用好Java。
说到Java的发展历程,就不能不提到它的新老两个东家——Sun(中文译为“太阳”)公司和Oracle(中文译为“甲骨文”)公司。先说Sun公司,事实上,Sun的本意并非是指“太阳”,而是指斯坦福大学校园网(Stanford University Network)的首字母缩写,跟“太阳”并没有关系。不过,由于这个缩写的蕴意不错,“太阳”就这样被叫开了。
1982年,Sun公司在斯坦福大学产业园“孵化”出来,后来成为一家大名鼎鼎的高科技IT公司,其全称是太阳微系统(Sun Microsystems)公司。Sun公司的主要产品是服务器和工作站,其产品极具竞争力,在自然市场成绩斐然。在硬件方面,公司于1985年研制出了自己的可扩充处理器架构(SPARC)精简指令集计算机(RISC)微处理器,能将服务器的性能提高很多;在软件方面,公司引以为傲的Solaris操作系统(UNIX的一个变种)比当时的Windows NT能更好地利用计算机资源,特别是在用户数量急剧上升、计算机系统变得非常庞大的情况下,Solaris的表现更佳。
20世纪90年代,互联网兴起。Sun公司就站在那个时代的潮流之上,所以它的服务器和工作站销量极佳,以至于这家公司在自己的广告中宣称:“我们就是.com前面的关键一点(We are the dot in the .com)。”言外之意,没有我们这画龙点睛的一点(服务器+操作系统),互联网公司就难以开起来。
Sun公司之所以敢于高抬自己,并不是吹嘘,它的实力的确非常雄厚,在当时足以傲视群雄。公司重要的软实力,就是人才济济。在任何年代,人才都是稀缺的(不光是21世纪)。
Sun公司创始人之一斯科特·麦克尼利(Scott McNealy)可谓一代“枭雄”,他非常重视研发。在他的主持下,Sun公司先后开发了基于SPARC系列的处理器、工作站和Solaris操作系统,这些产品为Sun公司带来了丰厚的利润。
但如果我们把格局放大一些的话,从科技史的角度来看,可能Sun公司给人类带来的最有意义的产品并不是前面提及的软件和硬件,而是我们即将要介绍的重要内容——Java编程语言。
现在让我们简单地回顾一下Java诞生的背景。在20世纪90年代,世界上的计算机大多处于两种状态:要么孤零零地“宅着”——不联网;要么小范围地“宅着”——企业内部局域网互联。那时可供公众分享的资源是非常有限的。
后来,随着互联网的蓬勃发展,就产生了不同类型的计算机系统相连接和信息共享的需求,亟需一种可跨越不同硬件和不同操作系统的新平台——这就是那个时代的“痛点”。任何时候,谁能解决时代的痛点,就意味着谁研制出了划时代的产品;谁能解决时代的痛点,就表明谁抓住了时代的发展方向。
Sun公司的创始人之一麦克尼利对网络计算有着超前的洞察力。在他的带领下,Sun公司的网络视野并未仅仅定格于计算机之间的互联,而是看得更远——计算机与非计算机彼此也是隔断的,它们也需要彼此连接!
在Sun公司,麦克尼利一直在推行“网络即计算机(The network is the computer)”的理念。这个关于无限连通世界的理念的表述,推动着Sun公司参与时代的发展。事实上,这个理念和现在大热的云计算理念也是一脉相承的。
2016年4月28日,全球移动互联网大会(Global Mobile Internet Conference,GMIC)在北京举行,当时的腾讯副总裁程武发表了《共享连接的力量》主题演讲。他提到,3年前,腾讯就提出“连接一切”的理念。无论连接人与人、人与服务,还是人与设备,互联网从根本上是在满足人的延伸需求,让网络中的个体获得更多的资源和能力,去实现更大的价值。
这样的认知其实是梅特卡夫定律(Metcalfe's Law)的体现,其内容是,网络的价值等于网络节点数的二次方,网络的价值与联网的用户数的二次方成正比。梅特卡夫认为,“连接”革命后,网络价值会飙升,网络中的个体有望实现更大的价值。
回顾起来,不论是现在流行的物联网(Internet of Things,IoT)概念,还是腾讯的“连接一切”理念,其实和Sun公司30多年前的理念都相差无几。因此可以说,Sun公司在那个时代的视角,不可谓不“高瞻远瞩”。
Sun公司认为,如果能把计算机和非计算机(主要指的是电子消费品,如家电等)系统这两者连接起来,将会带来一场计算机革命,这是一个巨大的机遇,而连接二者的媒介自然就是网络。
无限连通的世界,令人心动不已。但心动不如行动。Sun公司行动的结果,就是Java语言的诞生。
后来被称为Java之父的詹姆斯·戈斯林(James Gosling,又译为詹姆斯·高斯林)说:“放眼当时的市场,两个领域的厂家各自为政,没有形成统一的网络。因此很多时候人们不得不重复大量的实验,但这些问题其实早在30年前的计算机科学中已得到解决。”
其实核心问题在于,当时的电子消费品制造者压根就没有考虑使用网络,例如没有哪家生产商想生产一台会上网的冰箱。一流的企业,如苹果公司,是引导用户需求,而不是满足用户需求。因为有时候用户压根就不能明确自己的需求。
为了解决计算机与计算机之间、计算机与非计算机之间的跨平台连接,麦克尼利决定组建一个名叫Green的、由詹姆斯·戈斯林领衔的项目团队。该团队的目标是开发一种新的语言,并基于这种语言,研制专供下一代数字设备(如家电产品)和计算机使用的网络系统,这样就可以将通信和控制信息通过分布式网络发给电冰箱、电视机、烤面包机等家用电器,对它们进行控制和信息交流。想一想,这不正是当下很热门的物联网思维吗?
最初Green项目的工程师们准备采用C++实现这一网络系统。但C++比较复杂,最后经过裁剪、优化和创新,1990年,詹姆斯·戈斯林的研发小组基于C++开发了一种与平台无关的新语言Oak(即Java的前身)。Oak的名字源于詹姆斯·戈斯林办公室外的一棵枝繁叶茂的橡树,这在硅谷是一种很常见的树。
Oak主要用于为各种家用电器编写程序,Sun公司曾以Oak语言投标一个交互式电视项目,但结果被SGI(硅图公司,1982年成立于美国)打败。由于当时智能化家电的市场需求比较低迷,Oak的市场占有率并没有当初预期的高,于是“见风使舵”的Sun公司放弃了该项计划(事实上,“见风使舵”在市场决策中并不是一个贬义词,而是一种灵活的市场策略)。就这样,Oak几近“出师未捷身先死”。其实也不能全怪Sun公司,想一想,即使在30多年后的今天,物联网、智能家居的概念虽然很火,但接地气、成气候的项目屈指可数。
恰逢这时,Mark Ardreesen(美国软件工程师,曾创办网景通信公司)开发的Mosaic浏览器(互联网历史上第一个被普遍使用且能够显示图片的网页浏览器)和Netscape浏览器(网页浏览器,曾在市场中占据主导地位)启发了Oak项目组成员,让他们预见到Oak可能会在互联网应用上“大放异彩”,于是他们决定改造Oak。
项目组及时调整战略,把握住了时代的需求,于是Oak迎来了自己的“柳暗花明又一村”。也就是说,由于计算机与非计算机之间的连接这一想法太超前,Oak失败了,但是计算机与计算机之间的连接需求(更加接近那个时代的地气)又救活了Oak。
1995年5月23日,Oak改名为Java。至此,Java正式宣告诞生。Oak之所以要改名,其实也是情非得已,因为Oak作为一个商标,早已被一家显卡制造商注册了。Oak若想发展壮大,在法律层面上,改头换面势在必行。
其实Java本身也寓意十足,它是印度尼西亚的爪哇(注:Java的音译)岛的英文名称,该岛因盛产咖啡而闻名。这也是Java官方商标为一杯浓郁的咖啡的背后原因,而咖啡也是“爱”加班、“爱”熬夜的程序员们提神的最佳饮品之一,如下图所示。
Java标志
当时,Java最让人着迷的特性之一,就是它的跨平台性。在过去,计算机程序在不同的操作系统平台(如UNIX、Linux和Windows等)上移植时,程序员通常不得不重新调试与编译这些程序,有时甚至需要重写。
Java的优点在于,在设计之初就秉承了“一次编写,到处运行”(Write Once, Run Everywhere,WORE;有时也写成Write Once, Run Anywhere,WORA)的思想,这是Sun 公司为宣传Java语言的跨平台特性而提出的口号。
传统的程序通过编译可以得到与各种计算机平台紧密耦合(Coupling)的二进制代码。这种二进制代码可以在一个平台运行良好,但是换一个平台就“水土不服”,难以运行。
而Java的跨平台性,是指在一种平台下用Java语言编写的程序,在编译之后不用经过任何更改就能在其他平台上运行。例如,一个在Windows环境下开发出来的Java程序,在运行时,可以无缝地部署到Linux、UNIX或macOS环境之下;反之亦然,在Linux环境下开发的Java程序,同样可在Windows等其他平台上运行。Java是如何实现跨平台的呢?我们可用下面的图来比拟说明。
例如中国人(一个平台)说了一句问候语:“你好,世界!”美国人、法国人、德国人及日本人(其他平台)都能理解中国人的“问候”。之所以这样,是因为英语、法语、德语及日语翻译们进行了翻译。
Java的聪明之处在于,它用一个名为Java虚拟机(Java Virtual Machine,JVM)的机制屏蔽了这些“翻译”的细节。各国人尽管尽情地表达(编写Java代码),因为他们的“表达”经过编译,会形成各个平台通用的字节码(Byte Code),然后JVM“看平台下菜”,在背后默默地干起了“翻译沟通”的活。正是因为有JVM的存在,Java程序员才可以做到“一次编写,到处运行”——这也是Java的精华所在。
在经过一段时间的Java学习后,读者就会知道由Java源码编译出的二进制文件叫类(Class)文件,如果使用十六进制编辑器(如UltraEdit等)打开这个Class文件,你会发现这个文件最前面的32位将显示为“CA FE BA BE”,连接起来也就是词组“CAFE BABE ”(咖啡宝贝),如下图所示。每个Class文件的前4个字节都是这个标识,它们被称为“魔数”,主要用来确定该文件是否为一个能被JVM接受的Class文件。其另外一个作用就是,让诸如詹姆斯·戈斯林这类具有黑客精神的编程天才尽情表演,他们就是这样,在这些不经意的地方“雁过留声,人过留名”。
或许,麦克尼利看到了Java的这一优秀特性,在Java推出以后,Sun公司便赔钱做了大量的市场推广。仅3个月后,当时的互联网娇子之一——网景公司,便慧眼识珠,决定采用Java。
由于Java是新一代面向对象的程序设计语言,不受操作系统限制,在网络支持方面很强,加之对终端用户是免费的,因此它一下子就火了。很快,很多大公司如Oracle、Borland、SGI、IBM、AT&T和Intel等都纷纷加入了Java阵营。当Java逐渐成为Sun公司的标志时,Sun公司索性就把它的股票代码“SUNW”直接改为了“JAVA”。Sun公司对Java的重视程度,由此可见一斑。
1997年,Sun公司推出64位处理器,同年推出Java 2,Java渐渐风生水起,市场份额也越做越大。1998年,Java 2 按适用的环境不同,分化为4个派系(见下图):Java 2 Micro Edition(Java ME)、Java 2 Standard Edition(Java SE)、Java 2 Enterprise Edition(Java EE)以及Java Card。ME的意思是小型设备和嵌入系统,这个小小的派系,其实是Java诞生的“初心”。
(1)标准版(Standard Edition,Java SE):支持面向桌面级应用(如Windows操作系统下的应用程序)的Java平台,提供了完整的Java核心API(Application Programming Interface,应用程序接口),这个版本2005年以前被称为J2SE。
(2)企业版(Enterprise Edition,Java EE):以Java SE为基础向外延伸,增加了许多支持企业内部使用的扩充类,同时支持使用多层架构的企业应用[如企业资源计划(ERP)系统、客户关系管理(CRM)系统的应用]的Java平台。除了提供Java SE API外,Java EE还对其做了大量的扩充并提供了相关的部署支持。这个版本2005年以前被称为J2EE。
(3)微型版(Micro Edition,Java ME):Java ME同样以Java SE为基础,但相对精简。它所支持的只有核心类的子集合,它支持Java程序运行在移动终端(手机、PDA——掌上电脑)上的平台,加入了针对移动终端的支持。这个版本2005年以前被称为J2ME。Java ME主要进行嵌入式开发,目前渐渐被Android开发所替代。
(4)智能卡版(Java Card):由于服务对象定位更加明确化,Java Card版本比Java ME更加精简。它支持一些Java小程序运行在小内存设备(如容量小于64KB的智能卡)的平台上。
但是Java的技术平台不管如何划分,都是以Java SE为核心的,所以掌握Java SE十分重要,这也是本书的主要讲解内容。如果想进行Java EE的开发,Java SE是其中必要的组成部分,这也是为什么在学习Java EE之前要求读者一定要有扎实的Java SE基础。
当时专为连接智能家电而开发的Java,不曾想“有心栽花花不开,无心插柳柳成荫”,在家电市场毫无起色,却因其“一次编程,到处运行”的跨平台特性,赶上了互联网的高速发展时机,在企业级市场上大放异彩。
Java ME一度在翻盖手机应用上得到极大推广,成为当时的标配。但后来随着Android的兴起慢慢中落。Java之父詹姆斯·戈斯林后来也说,“Java ME已经做得足够好了,在当时是最强大的智能电话开发平台之一。不过现在渐渐被遗忘,因为Android太耀眼了。”
有起有落,螺旋上升,是事物发展的常态。Java的发展历程也不例外。Oracle Java平台开发副总裁、OpenJDK管理委员会核心成员乔治·萨博(Georges Saab)曾经这样说道:“在20世纪90年代,大多数程序员都把精力投入桌面应用的编写之上。到了2000年,一家美国宠物网站的成功吸引了大批的跟风者。业界又把焦点从桌面转移到了超文本标记语言(Hyper Text Markup Language,HTML)应用。随着智能电话和平板电脑的到来,基于触摸屏的移动应用又站在了潮流前端。所以对于下一个流行趋势是我们很难把握的,这涉及天时、地利、人和。”
然而,Java对于Sun公司来说是“华而不实”的资产。因为除了带来日渐高涨的声誉外,Java并没有直接给Sun公司带来与其声誉对等的回报。用华尔街的话来说,Java是赔钱赚吆喝。吆喝Java是赚到了,但盈利赚钱才是生存之道。
现在具备互联网思维的公司都知道,“免费”的目的是不免费,不免费的对象要发生转移,其实是要让“羊毛出在猪身上”,最后“让狗来买单”。但那是30多年前,那时Sun公司还没有很强的互联网赚钱思维,它到“死”(被Oracle公司收购)都没有想明白,为什么抱着一个金饭碗,却要不到饭。
事实上,除了生产处理器、服务器和操作系统之外,Sun公司还开发了办公软件OpenOffice。1995年到2000年是Sun公司高速发展的时期。这期间互联网飞速发展,它曾经和Oracle公司共同提出了网络计算机(Network Computer,NC)的概念 ,主要就是指没有硬盘的计算机,其实也就是低价台式机,是瘦客户机(或称无盘工作站)。
但在2000年之后,网络泡沫破碎,绝大多数的“.com”公司都关门了,苟延残喘活下来的公司,也急刹车般停止了扩张采购。服务器市场一下子低迷起来,Sun公司这个当初意气风发誓要成为互联网公司的“关键一点”的公司,已经不再关键了。老的盈利点(服务器市场)不盈利了,新的盈利点(如Java市场)又找不到,Sun公司突然陷入风雨飘摇的境地。
有道是“月满则亏,水满则溢”。Sun公司从1982年成立到2000年达到顶峰,用了将近20年,而走下坡路只用了一年。这种断崖式的毁灭,足以让今天的创业者引以为戒。
2008年爆发的金融危机,让持续亏损的Sun公司雪上加霜。到了2009年,由于业绩不佳,Sun公司的市值又比2007年下降了一半,终于跌到了对它觊觎已久的Oracle公司买得起的价格。2009年4月,市值曾经超过2000亿美元的Sun公司,在最低潮的时候,以74亿美元的便宜价被Oracle公司收购,这个价格仅仅为Sun公司顶峰市值的3%。作为Sun公司的核心资产之一的Java,自然也换了新东家——Oracle公司。
按照Oracle公司的老板拉里·埃里森(Larry Ellison,又译为拉里·埃利森)的话讲,Sun公司有很好的技术,也有很好的工程师,但它们的管理层实在是太烂了,而且做了很多错误的决策,这样才导致Oracle公司以很便宜的价格捡了漏[1]。
[1] 原话是:Sun's management “made some very bad decisions that damaged their business and allowed us to buy them for a bargain price.”
2015年5月23日,在北京中关村3W咖啡屋,笔者参加了由Oracle(中国)公司举办的Java诞生20周年庆典。在概括Java成功的原因时,Oracle公司的开发人员关系团队总监Sharat Chander总结了3点:社区排在第一,这是Java成功的基础;Java技术的不断进步排在第二;而排在第三位的,才是Oracle公司对Java的管理。
在收购Sun公司后,Oracle公司一方面继续积极推动Java社区发展,另一方面及时将社区成果反馈、集成到新版本产品中。Oracle公司承诺,大型版本的更新每两年发布一次,小型版本的更新每6个月发布一次。
在版本推新上,Oracle公司极其尊重Java社区的意见,Java 7就是在与社区深入交流的基础上推出的,尽管当时并非推出Java 7的最好时机,其后续功能在Java 8里进行了补全。
对于Java的发展,的确不能忽视Java社区的重要性。Oracle公司认为自己并非Java的管家,他们是在与Java社区一起来管理Java,而Java社区也被誉为Java成功的基础。对此Sharat Chander介绍,Java社区拥有314个Java用户组、900多万名Java程序员、超过150个Java 技术领袖。
2009年12月,Java企业版的升级版Java EE 6发布。2011年7月28日,Java SE 7发布。
CPU多核时代的兴起,让程序员们纷纷探索起怎么编写并行代码。一番折腾后大家发现,很多编程的好思想都来自一个叫函数式编程的程序范式。这个曾被束之高阁的好理念又被人重拾起来。2014年3月19日,Oracle公司发布Java 8.0正式版,提供了令大家望眼欲穿的Lambda。
2017年9月22日,Java 9正式发布。Java 9的众多特性中比较引人注目的有两条。第一条:jshell(Java脚本运行环境)。这是Java 9新增的一个脚本工具,有了这个工具,类似于Shell或Python,用户可以在命令行里直接运行Java的代码,而无须创建Java文件,然后再编译、运行。第二条:模块化(Modularity)。模块化是Java 9的一个新特性。模块的实质就是在包(Package)之上再提炼一层,即用模块来管理各种包,从而可以让代码更加安全,因为它可以指定哪些部分隐藏起来,哪些部分暴露给外部。
2019年9月17日,Java 13正式发布。Java 13拥有众多特性,其中比较引人注目的有以下两条。
第一条:动态应用程序类数据共享。Java 13对Java 10中引入的应用程序类数据共享进行了进一步的简化、改进和扩展,允许Java应用程序执行结束时动态进行类归档。第二条:增强垃圾回收特性(ZGC)释放未使用内存。在 Java 13 中,ZGC 将向操作系统返回被标识为长时间未使用的页面,这样它们将可以被其他进程复用。同时释放这些未使用的内存给操作系统不会导致堆大小缩小到参数设置的最小大小以下,如果将最小和最大堆大小设置为相同的值,则不会释放任何内存给操作系统。
当然,Java也不是没有缺点。曾经有人采访C++之父Bjarne Stroustrup,问他如何看待Java的简洁,他的回答却是时间不够长。大师之见,果然深邃。Java之美,早已不是简洁,而是开发上的高效,其为之付出的代价是各种类库、框架异常复杂而臃肿。通常,即使是一个专业级的Java程序员,也需耗费不菲的(包括时间上或金钱上的)学习成本。但这符合事物的发展规律,就像我们不能在期望一个横纲级的相扑运动员力大无穷的同时又期望他身轻如燕。
这就是我们的Java!它不甚完美,却非常能干!