精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Java>>技术言论>>mysunshine: Java与C/C++

主题:mysunshine: Java与C/C++
发信人: mysunshine()
整理人: zjxyz(2002-01-26 13:38:08), 站内信件
  Java语言是一种新型的面向对象的语言。它比C 或C++ 都易于学习和开发。
它与C 或C++ 并非完全不同,但是,在Java 中见不到C 及C++ 中复杂易出错的结
构,取而代之的是高可移植性和高安全性的特点使Java 应用程序(包括小应用程
序)在不同的网络环境中都能运行。Java 的主要问题在于它的某些特性(例如字
节码的检验及翻译、数组边缘检验、支持多线程结构、内存单元回收及平台无关
性)影响执行的开销。Java 的中立性需要在不同的平台上测试,同时它那被大大
夸张的可移植性是以性能损失为代价的。

 
  C、C++及Java的演变 

  自从1972 年,贝尔实验室的Dennis Ritchie 发明了C 语言之后, 它在全世
界广为流行(1 )。它的成功是由于那些有用途的特性(例如数据类型代表计算
机硬件的能力,规模较小及简单易学)。标准运行时库(用于输入/ 输出 、存贮
分配及字符串操作的功能) 以及一大套开发工具(UNIX 操作系统在这方面做出
很大贡献,其它的操作系统也紧随其后)。 

  时过境迁,计算机应用程序日益复杂,维护及扩展现存的C 语言应用程序成
了一件大事(2),这一切促成了C++ 语言的早期版本(普遍被称为“有类的C 语
言”),该版本在1980 年后被启用, 1983 年,现在使用的C++ 产生,到了198
7 年,C++开始被标准化。 C++ 语言是专为增加大型程序的可读性和易维护性而
设计的。C 语言被选择作为C++ 的蓝本是由于这是一种较低级的语言并适合系统
编程,另一个原因是已存的C 语言有大量应用程序和书籍,标准化机构规定C++ 
语言必须兼容C 语言,并且竭尽全力确保C 和C++ 之间的合法结构,避免重写任
何C 程序,手册及工具。这一切使得C语言程序员能够轻松地转向C++ 。 被迫与
C 语言的兼容使C++ 的问题重重。最主要的有:指针运算、数组索引、出边缘值
的检验、各种各样的函数参数以及未检验的类型转换。 

  Java 语言的发展始于1991年早期的Sun Microsystems。开始时,这是一个为
网络设备及用户电器设备开发软件的研究计划(3 )。在这个过程中(最后被称
为“绿”计划 ),James Gosling 及其他的项目工程师们对于可靠性,费用,标
准和简易性有了更多的认识。 到了1994 年中,Sun 公司的WWW 爆发了。“我们
意识到我们能做出很棒的浏览器”Gosling 说,“这是我们在客户/ 服务器主流
中所要完成 的几件奇怪的事情之一:中性结构、实时性、可靠性、安全性--那
些在工作站系统中不是那么重要的事。”那种语言即发展为今天的Java 。 


  Java 和C/C++的对比 

  Java 和C/C++ 有许多不同之处,我将按照主要特性一一对比:开发环境、性
能、可移植性(希望读者略懂Java 语言(4 ))。

 
  1 、语言特性 

  类型定义(Typedef) 、定义(define) 解释和预处理:(preprocessor) :这
一切在Java 中都不存在,以显得更简单,这些结构的删除使Java 对上下文的依
赖更小,程序员能够更简单地阅读和理解代码,并修改和重新使用代码(5 )。


  指针类型和算术运算:Java 语言并不直接使用指针,对象通过参数被实现,
即使参数实际上起到了指针的作用。Java 语言并不支持指针运算。 这个特性减
少了运行失误,在其它语言中,非法存取会导致程序或系统的崩溃,这是 C/C++
 和Java 的巨大差别之一。这个特性有以下的益处:Java 程序能在“sand box”
中被运行,更简单的代码的检验,更高的安全性。 

  枚举(Enumeration ) 类型:Java 语言不支持枚举( Enumeration ) 类型 
,而在C++ 中极为严格(比如:除非你使用显式的类型,C++ 编译器不会允许你
把不同枚举( Enumeration ) 类型相互转换。 你也不能对某种枚举(Enumeratio
n) 类型赋值)。

  结构、联合( Union ) 和函数:为了简便,Java 语言删去了结构和联合 。
结构和联合能通过使用类来实现(联合还可使用超类)。C 和C++ 能提供的函数
,通过正确使用类功能在Java中都能实现。 

  GOTO 语句:Java 语言取消了该语句以使程序更易读和易维护。 

  多重继承:C++ 支持多重继承,而Java 只能有一个超类,不过用户可通过界
面实现多重继承,并提供界面中没有的变量。 

  重载操作:在Java 语言中,程序员不能使标准算术符号重载,但是,通过声
明一组适当的实例变量和方法并对这些变量进行操作,程序员能够实现重载操作
。 

  浮点运算:Java 对浮点运算的要求似乎是对每个浮点运算都对浮点结果按精
度取整。对于为中间浮点结果而使用高精度的结构,Java要求运算器返回上一级
菜单相对自身能力所及低一些的中间结果。过多的精度位数必须按Java 定义削减
,这不仅导致了浮点运算精度的降低,也使Java 程序的执行开销有重大影响 。
这种情况C/C++ 中不存在(如想知道关于这个问题的详细信息,请参考Roger Go
llire的论文“First ImplementationArtifacts in Java ”)。 

  数组边缘检验:在Java 中,负的数组大小或界限外索引会导致运行出错,而
在 C/C++ 中,无该项错误检验功能。 

  字符串:Java 字符串是字符串类构成的事件,不象C 字符串 ,Java 字符串
是不可变的。字符串缓冲区(可变字符串对象)的类是Java 中可修改的字符串对
象。 

  类型体系:Java 语言定义了合法类型体系,正如C/C++ 支持C 风格体系 这
会导致类型冲突。 

  多线程:Java 语言支持多线 程结构,而C/C++ 语言无此特性。另一方面,
根据实现情况,对有些单线程Java 应用程序可能有性能开销。 

  内存单元回收:Java 语言支持内存单元回收,然而,程序不能 管理动态分
配的堆栈空间。但Java 的内存管理能跟踪对象参数。当一 个对象没有引用时,
即成为被内存单元回收的候选者。程序也能启动内存单元回收动作。这一装置在
C / C++ 中不存在。这一特性使得Java程序更易编写,然而,这功能无法关闭(
Java有" noasyncgc " 选项关闭不同步GC )对于需要实时响应的应用程序,内存
单元回收的开销可能成为问题。 

  网络:Java 语言支持网络动作,并隐藏接口界面,使客户/ 服务器应用程序
更容易开发。C 及C++ 并不提供此项功能。 


  2 、开发/运行环境 

  Java 在过去两年中获得大量推动。国际数据公司(IDC )估计在1997 年,
将有大约300,000 份Java 快速应用程序开发软件(RAD )集成开发环境(IDE)
工具的发货量。那是个令人印象深刻的数字。但与IDC 作出的,在年底前将有一
百二十八万开发商为C++ 许可而付费的估计相比仍然相形见拙。极少有C++ 开发
商改换门庭。IDC 预计90%以上现存拥 C++ 许可证的开发商将升级至其所选工具
的下一版本。 俄勒冈州波特兰的Market Decisions 公司对750 位开发商进行调
查。24% 说在过去六个月中C++ 是他们项目开发使用得最多的工具,比五个月前
类似调查结果的26%低。6%报告说Java为他们主要工具,是五个月前的两倍(6
 )。 由于Java 语言相对较新,可以理解开发所需工具尚未成熟。“我们认为决
定Java 渗透性的一个最好的指标是基于观察Java RAD 工具的增加。”Evan Qui
nn ,IDC 分析员说。他总结:“Java RAD 真正成熟 时,它会向客户机/ 服务器
发出挑战。”(6 ) 由于Java 执行环境与C 及C++ 不尽相同,性能始终是重要
的事。Java 应用程序是解释程序而非?C/C++ 程序那样是经过编译后与本地代码
连接。 Java 应用程序首先被编译为字节代码,然后在本地或通过网络在远程虚
拟机上解释。Java 字节代码规模较小,然而每次调用时相同代码都会被解释。因
此其性能较同类产品为慢。(即如果代码用Java 编写), 即时(JIT )编译器将
字节代码翻译为本地码而执行。它提高了性能,因为翻译只做一次,而不是每次
被调用时都做。JIT 虽提高了Java 的性能,但在本地码执行速度上尚有不足。希
望本地Java 编译器能解决这一问题。 


  3 、可移植性 

  C/C++ 程序被移植到其它机器上时一般会遇到问题。例如:这些语言没有分
配初始数据类型的标准。在转换初始类型时,C及C++ 不指定正确结果。Java 语
言为有Java 虚拟机的计算机上运行的应用程序而设计。Java 的口号“编写一次
,任意运行”即其指导性的目标。 然而,由于Java 运行时在不同的主机上完成
,它有主机特定的模块 。我们怎么能不先试验而保证一个Java 应用程序在不同
的平台上总会有相同的性能呢?例如,根据主机操作系统不同线程调度。 一个多
线程的Java 应用程序可能在不同计算机环境下有不同性能。一个“100%纯Java
 ”(100% Pure Java)应用程序应该在不同平台上测试以保证其质量。 Java 
程序比C 及C++ 有更强的可移植性。 但为了质量原因仍建议 Java 程序,以及 
C 和C++ 程序,在不同平台上进行测试。如今市场上有各种各样的虚拟机(VM)
,但不清楚VM 测试组件有多全面。 


  4 、性能 

  C++ 被认为比Java 更成熟。在对众多Java 软件开发商的采访中,CNET 的N
EWS.COM 发现许多软件商在他们的Java 应用程序中使用了一定量的本地码(Nat
ive Cade)。这些公司包括IBM,Netscape, Microsoft, DimesionX,RandomNois
e 及Net Dynamics(7)。 由于各种理由,许多发展商发现要完全用Java 代码编
写应用程序虽非不可能,却也相当困难。一种普遍的理由是性能与C 版本相比,
经解释的Java 代码较慢。(1996 年8 月报告慢10倍(8),1997 年5 月报告慢
10 到20 倍(9))。JIT 编译器改善了这一状况。(速度增加10 到25 倍(8)
,1997 年6 月报告速度增加1 到4 倍(10))。Java 本地编译器希望能提供三
者中最佳性能(Asymetrix宣布速度增加50倍(8 ),4到7 倍(10 ))。 

  一般来说,Java 语言不提供用于人工最优设置的标准钩子(hook) (如C/C+
+的注册关键字(register keyword) 或 asm )。Java 不支持内嵌本地汇编代码
以帮助编译器代码形成。在Java 设计中,简易性和可移植性是比性能更重要的因
素。Java 更依靠编译器和运行时提供性能。根据Market Decision 公司(位于波
特兰的一家独立研究公司),96% 的Java 发展商正在开发、配置Windows 中的J
ava 应用软件--是Java 发展商配置在任何其它平台上的应用程序的两倍多(12
)。而大部分Java 应用程序在英特尔架构的平台上运行。 Java 的浮点语法要求
这样一种结构,它能提供更高的中间操作的解决方法,而放弃精确性。这一要求
不仅导致Java 程序较低的精确性,而且也损害了应用程序的性能。仅就这一点上
,Java 并未完全使用处理器的能力。由于Java 宣布应用程序会因为低准确性而
在运行时间上付出代价,它不太可能用作浮点运算深层次应用程序的主要语言。
 如果考虑到在Java 语言语法中,每次方法调用都需查找方法列表,Java 的运行
时调用通常比C 的高而与C++ 相仿。Java 的错误查找比C 及C++ 要求更长的运行
时。有理由得出这样的结论:有了一个好的本地Java 编译器,Java 性能能与C+
+ 性能相仿。 


  结论 

  与C++ 一样,Java 是面向对象的语言但更简单。对C 和C++ 程序员来说,J
ava 应该并不陌生,因为Java ,C 和C++ 有相似的语言结构。在 C++ 语言上去
除了一些复杂功能并加入错误检查,内存单元回收和多线程的支持后,Java 程序
应该会相对来说更强壮。具有内置的安全特性,Java 应用程序可用Java 虚拟机
在多种网络环境中解释。目前,Java 开发环境成熟性不能与本地C/C++ 相比,J
ava 代码解释速度较慢。JIT 编译器和Java 本地编译器虽然正在不断改进,但尚
不能证明其与C/ C++ 已经成为竞争对手。 Java 开发商必须在对Java 的期望中
现实一些(13 )。Java 所提供的不 是传统意义上的语言,也是一种完整的环境
--虚拟机和网络环境(包括Internet )。要被作为一种主流语言采用,Java 
必须有完整的功能,简单易用并可靠,而且运行成本低。这一随处可见的新语言
仍需作许多改进。 

  

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 155.69.4.55]

[关闭][返回]