我看到,很多人在问:我是否应该学习JAVA;我看到,很多人在问:JAVA和C++哪个更好?
我想我没有资格回答这些问题。但我想CUJ有资格。本文出自CUJ的import.java.*专栏 ——以CUJ而开设JAVA专栏,这本身已经证明广大C++程序员对JAVA的重视程度。究竟哪个好?好在何处?是否应该学?应该怎样学?应该学什么?……太多的问题。希望本文能起抛砖引玉之效。希望本文的读者能亲自看看这些专家指点,从而形成自己的判断。
本文作者Chuck Allison对程序设计有丰富的经验,并且有多年使用C++的历史。而我也是一个C++的狂热爱好者。因此,我想这篇文章应该很对你——C++开发者——的胃口。
一次JAVA旅游的质量取决于本次旅游的向导。我们是幸运的,Chuck Allison是一个经验丰富的向导,无论对于C++还是对于JAVA都是。
--------------------------------------------------------------------------------
再一次向你问好。“import java.*”欢迎你们——C/C++程序员们——来学习JAVA。在你以前的案例中,你可能有很多理由想要这样做。JAVA远不止是一种增强WEB页面的机制。它是一种用途广泛的面向对象程序设计语言,它建立在对软件工程工业的许多需求之上。当你开始学习JAVA之后,你将成为一个更好的C/C++程序员,因为JAVA的语法与C++非常相似。并且,如果你是一个喜欢面向对象编程原则的C++程序员,你将感到象是回到了自己的家。就如同很多C程序员选择了C++一样,许多C++程序员正在寻找自然转向JAVA的途径。
我将分析JAVA所有的特征:语言、库、以及思想,但是从C/C++的视角。这意味着我不是一个JAVA的盲目信仰者(可能是一个狂热爱好者,但不是一个盲目信仰者:-))。实际上,我对C++的掌握和爱好可能在某些时候让我偏向另一个方向。这也意味着我将可能做一些坏不堪言的事情:我将比较这两种语言并尝试说明一些有用的东西。在这篇文章中,我只提供对JAVA的一个大概的观察,而把具体的教学留在将来的部分中。但首先,我让你看一点背景。
关于“骗局”的一些话
在1984年与Apple MacIntosh的联系中,我第一次听到了“面向对象”这个术语。当我问“面向对象是什么意思”时,他们胡乱说了一通关于屏幕上的图形对象的话。这就是一个神话:图形化用户接口让某些东西变得面向对象。
在20世纪80年代中期,“面向对象”这个术语被滥用,以至于刺穿这个骗局唯一的方法就是:找到一种毫无疑义的面向对象编程语言并使用它。当我在1987年发现LISP时,我开始领悟面向对象的思想,并对“语言对封装、继承和多态的支持”有了第一手的经验。
在那一年的晚些时候,我参加了某个关系数据库管理系统(relational DBMS)厂商的现场销售演示会。我已经非常精通他们的产品,并且我是我们公司内的“专家”。在演示会的过程中我听到这样的说法:“<产品X>是面向对象的。”我跑到前面问那位演示者:“你说<产品X>是面向对象的,这是什么意思?”然后我在整个演示会中再也不说一句话。其后的讨论表明,<产品X>根本不是面向对象的——它只是他们经常说的一种东西:骗局。
你也许知道,70年代的时髦词汇是“结构化设计”,它最终在80年代的工业中得到了很好的应用;80年代的骗局是“面向对象”,而它正是今天的正统。那么,今天的骗局是什么?模式,我猜;以及,是的,JAVA。
基础 vs. 骗局
C++的声望在没有任何推销的情况下如此爆炸性的增长,这是件有趣的事。在1982年,C++的设计者Bjarn Stroustrup面临一个困难的选择:对“C with Classes”(后来被命名为C++)的用户的支持吞噬掉了他一大半的时间,但还没有足够的用户让他有资金成立一个正式机构。对于这种情况,Bjarne说:
“我看只有两种脱离困境的办法:
1. 停止支持C with Classes。
2. 开发一种更好的新语言,使它拥有足够多的用户,以获得足够的资金来支持和发展一个机构。当时我估计至少需要5000个工业用户。
第三种选择——通过推销(骗局)来增加用户数量——从来没有在我的脑海中出现过[1]。”
在1991年,C with Classes诞生后的第12年,C++的用户数量已经达到了四十万,而且这个数量每7.5个月就翻一番[2]。(一点点数学知识告诉我:如果这个增长率一直保持下去,到2000年时地球上的每个人都将是C++开发者——一个真正可怕的Y2K问题!)
因为没有计划周密的销售计划,而且,因为C++是如此“复杂的语言”(也许我们曾经听到过这种说法),我们可以相当有把握的说:C++只靠它的技术优势成为了面向对象开发工具的领袖。就和以前的C语言一样,C++从基础做起,它满足开发者的热情,它不断增强自己的能力以满足更多的需要。
但是,C++快速成长的故事与JAVA的故事没有任何相似之处。
JAVA人
在Bruce Eckel——著名的作者和教授——的JAVA公开讨论会上,他送给每个与会者一件T-shirt。当你穿上它时,在你的左胸上有一个图案:一个原始人正为生活而奔波。Bruce将这个人叫做“JAVA人”,因为他正代表着你和我和大多数现代计算机工业的从业者——我们正试图跟上JAVA的浪潮。稍微浏览一下JAVA库,你就会看到这个浪潮发展的速度。当太阳微系统公司(SUN)在1995年中期推出JDK(JAVA开发包)版本1.0时,它的库里有212个类和接口。其后1997年的1.1版有504个。现在的1.2版JDK库中有1592个类和接口(以及13635个方法),而且它还在beta测试阶段中!而且,好象几个新增加的语言特性(内嵌类、新的事件模型、Swing组件、可插入VM体系等等)还不足以让我们的脑子和手指忙乱似的,JAVA的每个版本还都会反对以前的许多类和方法——我们还必须忘掉他们。
美国公司在应用新技术方面都有略微保守的传统。我所工作过的三家大公司都只首先选用ANSI标准定义过的编程语言。这就是我在1978年我的第一份工作中仍然使用Fortran的原因。直到1986年,我才偷偷在我的工作中引入了C语言——C语言的标准化在几年之后才完成,但它当时已经有16年的历史、而且非常稳定。我第一次能正式在工作中使用C++是在1994年——在它被发明之后的第15年、公开之后的第9年、标准化之后的第5年。一般来说,IT公司只使用那些“得到验证的技术。”
那么,为什么几乎所有主要的软件厂商都不顾新的JAVA语言的不稳定性而飞快的提供了JAVA工具来跟上需要呢?为什么JAVA能对这么多通常谨小慎微的大公司造成如此的影响呢?相关的事件还包括:我在这个春天向一家非常保守的公司传授JAVA的知识,这样他们可以用JAVA来重写他们的国内记帐系统。这是为什么?
当然,答案很简单:Internet。当访问Internet已经成为家庭日常时,JAVA来了。“自由发布”当然没有错,但正是Internet让“自由发布”切实可行。添加applet的能力是无可争议的。applet让静态的页面活动起来,这从我国的CFO们手中诱惑出了无数的美圆。
所以,骗局——呃,我是指,推销——是答案中理所当然的一部分。在1996年我与Bjarn Stroustrup的一次会见中,我问他对“JAVA革命”有什么想法。他回答我:
“如果我没有兼容C语言的约束,我肯定也不会设计出JAVA这样的语言。可是,SUN能靠它获得如此多的美圆,这让我感到惊讶。这是不会被忘记的一课,并且这将是单个程序员、小公司和学院的恶兆。如果人们坚持要对C++和JAVA进行比较——看起来他们正在这样做——我建议他们看看D&E(The Design and Evolution of C++),看看C++为什么是现在这个样子,并考虑这两种语言在设计标准中的效果。C++和JAVA的差异不止是表面上的,并且不可能有哪个语言拥有所有的优点。[3]
牛肉在哪里?
推销可能可以吸引我们的注意力,但不能保证持续的成功。尽管JAVA革命仍在继续,但现在Javascript和GIF动画已经做了我们以前用applet做的大多数工作。JAVA获得持续的成功,那是因为在骗局的背后它有自己的价值。JAVA对程序员有吸引力,因为它是一种干净的、设计良好的软件开发工具,并且学习它不是“太困难”。JAVA对开发投资者有吸引力,因为它强调对象和包,还因为它的虚拟机体系,因为它支持可控的、划算的、(通常)安全的应用程序建造、发布途径。除了操作系统厂商之外,所有人都喜欢“编写一次,到处运行”的概念。而且JAVA对网络编程举世无双的支持让它在电子商务领域中获胜。让我们面对这样一个事实:JAVA很酷!
但是,不要就这样把你的C++编译器搁置起来。JAVA不可能做所有事。这也就是它支持JNI(JAVA固有接口)的原因。在运行速度确实重要的地方,C++仍然是胜利者(至少现在是)。而且,尽管SUN已经发布了嵌入式JAVA的规范,你仍然可以肯定:JAVA取代C作为嵌入式编程混合语言还需要一段时间。
另外,JAVA并不象你想象的那么容易学习。在我前面提到过的为某公司进行的教学的第四天,相当数量的学生带着疲惫的表情说:“伙计,这并不象我想象的那么容易!”(在我的记忆中,那天我们在谈论对象克隆、反射和I/O。)我想Larry O'Brien做出了最好的总结,他说:“说‘JAVA比C++简单’,就好象说‘2000年比珠穆朗玛峰短’一样。”JAVA是复杂的,但复杂的方式与C++不同。它是否真的更简单,这取决于你和你的需要。解决实际问题从来不会容易,不管你使用什么工具。
缺少了什么?
JAVA来自Oak,一种剥除了C++的一些特性以用于嵌入式系统的语言。虽然你现在从JDK里得到的JAVA比Oak大(并且不再适用于嵌入式应用),但JAVA还是不支持C++的下列特性:
显式指针和引用
delete运算符
析构子
&