“做为一名C++程序员,咱们早已掌握了面向对象程序设计的基本概念,并且Java的语法无疑是很是熟悉的。事实上,Java原本就是从C++衍生出来的。”
然而,C++和Java之间仍存在一些显著的差别。能够这样说,这些差别表明着技术的极大进步。一旦咱们弄清楚了这些差别,就会理解为何说Java是一种优秀的程序设计语言。本附录将引导你们认识用于区分Java和C++的一些重要特征。
(1) 最大的障碍在于速度:解释过的Java要比C的执行速度慢上约20倍。不管什么都不能阻止Java语言进行编译。写做本书的时候,刚刚出现了一些准实时编译器,它们能显著加快速度。固然,咱们彻底有理由认为会出现适用于更多流行平台的纯固有编译器,但倘若没有那些编译器,因为速度的限制,必须有些问题是Java不能解决的。
(2) 和C++同样,Java也提供了两种类型的注释。
(3) 全部东西都必须置入一个类。不存在全局函数或者全局数据。若是想得到与全局函数等价的功能,可考虑将static方法和static数据置入一个类里。注意没有象结构、枚举或者联合这一类的东西,一切只有“类”(Class)!
(4) 全部方法都是在类的主体定义的。因此用C++的眼光看,彷佛全部函数都已嵌入,但实情并不是如何(嵌入的问题在后面讲述)。
(5) 在Java中,类定义采起几乎和C++同样的形式。但没有标志结束的分号。没有class foo这种形式的类声明,只有类定义。
class aType()
void aMethod() {/* 方法主体*/}
}
(6) Java中没有做用域范围运算符“::”。Java利用点号作全部的事情,但能够不用考虑它,由于只能在一个类里定义元素。即便那些方法定义,也必须在一个类的内部,因此根本没有必要指定做用域的范围。咱们注意到的一项差别是对static方法的调用:使用ClassName.methodName()。除此之外,package(包)的名字是用点号创建的,并能用import关键字实现C++的“#include”的一部分功能。例以下面这个语句:
import java.awt.*;
(#include并不直接映射成import,但在使用时有相似的感受。)
(7) 与C++相似,Java含有一系列“主类型”(Primitive type),以实现更有效率的访问。在Java中,这些类型包括boolean,char,byte,short,int,long,float以及double。全部主类型的大小都是固有的,且与具体的机器无关(考虑到移植的问题)。这确定会对性能形成必定的影响,具体取决于不一样的机器。对类型的检查和要求在Java里变得更苛刻。例如:
■条件表达式只能是boolean(布尔)类型,不可以使用整数。
■必须使用象X+Y这样的一个表达式的结果;不能仅仅用“X+Y”来实现“反作用”。
(8) char(字符)类型使用国际通用的16位Unicode字符集,因此能自动表达大多数国家的字符。
(9) 静态引用的字串会自动转换成String对象。和C及C++不一样,没有独立的静态字符数组字串可供使用。
(10) Java增添了三个右移位运算符“>>>”,具备与“逻辑”右移位运算符相似的功用,可在最末尾插入零值。“>>”则会在移位的同时插入符号位(即“算术”移位)。
(11) 尽管表面上相似,但与C++相比,Java数组采用的是一个颇为不一样的结构,并具备独特的行为。有一个只读的length成员,经过它可知道数组有多大。并且一旦超过数组边界,运行期检查会自动丢弃一个异常。全部数组都是在内存“堆”里建立的,咱们可将一个数组分配给另外一个(只是简单地复制数组句柄)。数组标识符属于第一级对象,它的全部方法一般都适用于其余全部对象。
(12) 对于全部不属于主类型的对象,都只能经过new命令建立。和C++不一样,Java没有相应的命令能够“在堆栈上”建立不属于主类型的对象。全部主类型都只能在堆栈上建立,同时不使用new命令。全部主要的类都有本身的“封装(器)”类,因此可以经过new建立等价的、之内存“堆”为基础的对象(主类型数组是一个例外:它们可象C++那样经过集合初始化进行分配,或者使用new)。
(13) Java中没必要进行提早声明。若想在定义前使用一个类或方法,只需直接使用它便可——编译器会保证使用恰当的定义。因此和在C++中不一样,咱们不会碰到任何涉及提早引用的问题。
(14) Java没有预处理机。若想使用另外一个库里的类,只需使用import命令,并指定库名便可。不存在相似于预处理机的宏。
(15) Java用包代替了命名空间。因为将全部东西都置入一个类,并且因为采用了一种名为“封装”的机制,它能针对类名进行相似于命名空间分解的操做,因此命名的问题再也不进入咱们的考虑之列。数据包也会在单独一个库名下收集库的组件。咱们只需简单地“import”(导入)一个包,剩下的工做会由编译器自动完成。
(16) 被定义成类成员的对象句柄会自动初始化成null。对基本类数据成员的初始化在Java里获得了可靠的保障。若不明确地进行初始化,它们就会获得一个默认值(零或等价的值)。可对它们进行明确的初始化(显式初始化):要么在类内定义它们,要么在构建器中定义。采用的语法比C++的语法更容易理解,并且对于static和非static成员来讲都是固定不变的。咱们没必要从外部定义static成员的存储方式,这和C++是不一样的。
(17) 在Java里,没有象C和C++那样的指针。用new建立一个对象的时候,会得到一个引用(本书一直将其称做“句柄”)。例如:
String s = new String("howdy");
然而,C++引用在建立时必须进行初始化,并且不可重定义到一个不一样的位置。但Java引用并不必定局限于建立时的位置。它们可根据状况任意定义,这便消除了对指针的部分需求。在C和C++里大量采用指针的另外一个缘由是为了能指向任意一个内存位置(这同时会使它们变得不安全,也是Java不提供这一支持的缘由)。指针一般被看做在基本变量数组中四处移动的一种有效手段。Java容许咱们以更安全的形式达到相同的目标。解决指针问题的终极方法是“固有方法”(已在附录A讨论)。将指针传递给方法时,一般不会带来太大的问题,由于此时没有全局函数,只有类。并且咱们可传递对对象的引用。Java语言最开始声称本身“彻底不采用指针!”但随着许多程序员都质问没有指针如何工做?因而后来又声明“采用受到限制的指针”。你们可自行判断它是否“真”的是一个指针。但无论在何种状况下,都不存在指针“算术”。
(18) Java提供了与C++相似的“构建器”(Constructor)。若是不本身定义一个,就会得到一个默认构建器。而若是定义了一个非默认的构建器,就不会为咱们自动定义默认构建器。这和C++是同样的。注意没有复制构建器,由于全部自变量都是按引用传递的。
(19) Java中没有“破坏器”(Destructor)。变量不存在“做用域”的问题。一个对象的“存在时间”是由对象的存在时间决定的,并不是由垃圾收集器决定。有个finalize()方法是每个类的成员,它在某种程度上相似于C++的“破坏器”。但finalize()是由垃圾收集器调用的,并且只负责释放“资源”(如打开的文件、套接字、端口、URL等等)。如需在一个特定的地点作某样事情,必须建立一个特殊的方法,并调用它,不能依赖finalize()。而在另外一方面,C++中的全部对象都会(或者说“应该”)破坏,但并不是Java中的全部对象都会被看成“垃圾”收集掉。因为Java不支持破坏器的概念,因此在必要的时候,必须谨慎地建立一个清除方法。并且针对类内的基础类以及成员对象,须要明确调用全部清除方法。
(20) Java具备方法“过载”机制,它的工做原理与C++函数的过载几乎是彻底相同的。
(21) Java不支持默认自变量。
(22) Java中没有goto。它采起的无条件跳起色制是“break 标签”或者“continue 标准”,用于跳出当前的多重嵌套循环。
(23) Java采用了一种单根式的分级结构,所以全部对象都是从根类Object统一继承的。而在C++中,咱们可在任何地方启动一个新的继承树,因此最后每每看到包含了大量树的“一片森林”。在Java中,咱们不管如何都只有一个分级结构。尽管这表面上看彷佛形成了限制,但因为咱们知道每一个对象确定至少有一个Object接口,因此每每能得到更强大的能力。C++目前彷佛是惟一没有强制单根结构的惟一一种OO语言。
(24) Java没有模板或者参数化类型的其余形式。它提供了一系列集合:Vector(向量),Stack(堆栈)以及Hashtable(散列表),用于容纳Object引用。利用这些集合,咱们的一系列要求可获得知足。但这些集合并不是是为实现象C++“标准模板库”(STL)那样的快速调用而设计的。Java 1.2中的新集合显得更加完整,但仍不具有正宗模板那样的高效率使用手段。
(25) “垃圾收集”意味着在Java中出现内存漏洞的状况会少得多,但也并不是彻底不可能(若调用一个用于分配存储空间的固有方法,垃圾收集器就不能对其进行跟踪监视)。然而,内存漏洞和资源漏洞可能是因为编写不当的finalize()形成的,或是因为在已分配的一个块尾释放一种资源形成的(“破坏器”在此时显得特别方便)。垃圾收集器是在C++基础上的一种极大进步,使许多编程问题消弥于无形之中。但对少数几个垃圾收集器力有不逮的问题,它倒是不大适合的。但垃圾收集器的大量优势也使这一处缺点显得微不足道。
(26) Java内建了对多线程的支持。利用一个特殊的Thread类,咱们可经过继承建立一个新线程(放弃了run()方法)。若将synchronized(同步)关键字做为方法的一个类型限制符使用,相互排斥现象会在对象这一级发生。在任何给定的时间,只有一个线程能使用一个对象的synchronized方法。在另外一方面,一个synchronized方法进入之后,它首先会“锁定”对象,防止其余任何synchronized方法再使用那个对象。只有退出了这个方法,才会将对象“解锁”。在线程之间,咱们仍然要负责实现更复杂的同步机制,方法是建立本身的“监视器”类。递归的synchronized方法能够正常运做。若线程的优先等级相同,则时间的“分片”不能获得保证。
(27) 咱们不是象C++那样控制声明代码块,而是将访问限定符(public,private和protected)置入每一个类成员的定义里。若未规定一个“显式”(明确的)限定符,就会默认为“友好的”(friendly)。这意味着同一个包里的其余元素也能够访问它(至关于它们都成为C++的“friends”——朋友),但不可由包外的任何元素访问。类——以及类内的每一个方法——都有一个访问限定符,决定它是否能在文件的外部“可见”。private关键字一般不多在Java中使用,由于与排斥同一个包内其余类的访问相比,“友好的”访问一般更加有用。然而,在多线程的环境中,对private的恰当运用是很是重要的。Java的protected关键字意味着“可由继承者访问,亦可由包内其余元素访问”。注意Java没有与C++的protected关键字等价的元素,后者意味着“只能由继承者访问”(之前可用“private protected”实现这个目的,但这一对关键字的组合已被取消了)。
(28) 嵌套的类。在C++中,对类进行嵌套有助于隐藏名称,并便于代码的组织(但C++的“命名空间”已使名称的隐藏显得多余)。Java的“封装”或“打包”概念等价于C++的命名空间,因此再也不是一个问题。Java 1.1引入了“内部类”的概念,它秘密保持指向外部类的一个句柄——建立内部类对象的时候须要用到。这意味着内部类对象也许能访问外部类对象的成员,毋需任何条件——就好象那些成员直接隶属于内部类对象同样。这样便为回调问题提供了一个更优秀的方案——C++是用指向成员的指针解决的。
(29) 因为存在前面介绍的那种内部类,因此Java里没有指向成员的指针。
(30) Java不存在“嵌入”(inline)方法。Java编译器也许会自行决定嵌入一个方法,但咱们对此没有更多的控制权力。在Java中,可为一个方法使用final关键字,从而“建议”进行嵌入操做。然而,嵌入函数对于C++的编译器来讲也只是一种建议。
(31) Java中的继承具备与C++相同的效果,但采用的语法不一样。Java用extends关键字标志从一个基础类的继承,并用super关键字指出准备在基础类中调用的方法,它与咱们当前所在的方法具备相同的名字(然而,Java中的super关键字只容许咱们访问父类的方法——亦即分级结构的上一级)。经过在C++中设定基础类的做用域,咱们可访问位于分级结构较深处的方法。亦可用super关键字调用基础类构建器。正如早先指出的那样,全部类最终都会从Object里自动继承。和C++不一样,不存在明确的构建器初始化列表。但编译器会强迫咱们在构建器主体的开头进行所有的基础类初始化,并且不容许咱们在主体的后面部分进行这一工做。经过组合运用自动初始化以及来自未初始化对象句柄的异常,成员的初始化可获得有效的保证。
public class Foo extends Bar {
public Foo(String msg) {
super(msg); // Calls base constructor
}
public baz(int i) { // Override
super.baz(i); // Calls base method
}
}
(32) Java中的继承不会改变基础类成员的保护级别。咱们不能在Java中指定public,private或者protected继承,这一点与C++是相同的。此外,在衍生类中的优先方法不能减小对基础类方法的访问。例如,假设一个成员在基础类中属于public,而咱们用另外一个方法代替了它,那么用于替换的方法也必须属于public(编译器会自动检查)。
(33) Java提供了一个interface关键字,它的做用是建立抽象基础类的一个等价物。在其中填充抽象方法,且没有数据成员。这样一来,对于仅仅设计成一个接口的东西,以及对于用extends关键字在现有功能基础上的扩展,二者之间便产生了一个明显的差别。不值得用abstract关键字产生一种相似的效果,由于咱们不能建立属于那个类的一个对象。一个abstract(抽象)类可包含抽象方法(尽管并不要求在它里面包含什么东西),但它也能包含用于具体实现的代码。所以,它被限制成一个单一的继承。经过与接口联合使用,这一方案避免了对相似于C++虚拟基础类那样的一些机制的须要。
为建立可进行“例示”(即建立一个实例)的一个interface(接口)的版本,需使用implements关键字。它的语法相似于继承的语法,以下所示:
public interface Face {
public void smile();
}
public class Baz extends Bar implements Face {
public void smile( ) {
System.out.println("a warm smile");
}
}
(34) Java中没有virtual关键字,由于全部非static方法都确定会用到动态绑定。在Java中,程序员没必要自行决定是否使用
文章出处:飞诺网(http://dev.firnow.com/course/3_program/c++/cppjs/20090403/164032.html)
JAVA和C++都是面向对象语言。也就是说,它们都可以实现面向对象思想(封装,继承,多态)。而因为C++为了照顾大量的C语言使用者, 而兼容了C,使得自身仅仅成为了带类的C语言,多多少少影响了其面向对象的完全性!JAVA则是彻底的面向对象语言,它句法更清晰,规模更小,更易学。它是在对多种程序设计语言进行了深刻细致研究的基础上,据弃了其余语言的不足之处,从根本上解决了c++的固有缺陷。 Java和c++的类似之处多于不一样之处,但两种语言几处主要的不一样使得Java更容易学习,而且编程环境更为简单。html
转自:http://club.topsage.com/thread-265349-1-1.htmljava
Java并不只仅是C++语言的一个变种,它们在某些本质问题上有根本的不一样: c++
(1)Java比C++程序可靠性更高。有人曾估计每50行C++程序中至少有一个BUG。姑且不去讨论这个数字是否夸张,可是任何一个C++程序员都不得不认可C++语言在提供强大的功能的同时也提升了程序含BUG的可能性。Java语言经过改变语言的特性大大提升了程序的可靠性。 程序员
(2)Java语言不须要程序对内存进行分配和回收。Java丢弃了C++ 中不多使用的、很难理解的、使人迷惑的那些特性,如操做符重载、多继承、自动的强制类型转换。特别地,Java语言不使用指针,并提供了自动的废料收 集,Examda提示: 在Java语言中,内存的分配和回收都是自动进行的,程序员无须考虑内存碎片的问题。 算法
(3)Java语言中没有指针的概念,引入了真正的数组。不一样于C++中利用指针实现的“伪数组”,Examda,Java引入了真正的数组,同时将 容易形成麻烦的指针从语言中去掉,这将有利于防止在c++程序中常见的由于数组操做越界等指针操做而对系统数据进行非法读写带来的不安全问题。 编程
(4)Java用接口(Interface)技术取代C++程序中的多继承性。接口与多继承有一样的功能,可是省却了多继承在实现和维护上的复杂性。 数组
Java和C++各有各的优点,无需争论那种语言好,哪一种语言很差,可以存在就必定有它的优点,只要你决定了要学编程就扎实的学好,编程语言都是相同的,学会一种,其余的学起来就很容易了。安全
具体来讲有如下几点:ruby
1.指针 JAVA语言让编程者没法找到指针来直接访问内存,而且增添了自动的内存管理功能,从而有效地防止了c/c++语言中指针操做失误,如野指针所形成的系统崩溃。但也不是说JAVA没有指针,虚拟机内部仍是使用了指针,只是外人不得使用而已。这有利于Java程序的安全。多线程
2.多重继承 c++支持多重继承,这是c++的一个特征,它容许多父类派生一个类。尽管多重继承功能很强,但使用复杂,并且会引发许多麻烦,编译程序实现它也很不容易。Java不支持多重继承,但容许一个类继承多个接口(extends+implement),实现了c++多重继承的功能,又避免了c++中的多重继承实现方式带来的诸多不便。
3. 数据类型及类 Java是彻底面向对象的语言,全部函数和变量都必须是类的一部分。除了基本数据类型以外,其他的都做为类对象,包括数组。对象将数据和方法结合起来,把它们封装在类中,这样每一个对象均可实现本身的特色和行为。而c++容许将函数和变量定义为全局的。此外,Java中取消了c/c++中的结构和联合,消除了没必要要的麻烦。
4. 自动内存管理 Java程序中全部的对象都是用new操做符创建在内存堆栈上,这个操做符相似于c++的new操做符。下面的语句由一个创建了一个类Read的对象,而后调用该对象的work方法:
Read r=new Read(); r.work();
语句Read r=new Read();在堆栈结构上创建了一个Read的实例。Java自动进行无用内存回收操做,不须要程序员进行删除。而c++中必须由程序贝释放内存资源, 增长了程序设计者的负扔。Java中当一个对象不被再用到时,无用内存回收器将给它加上标签以示删除。JAVA里无用内存回收程序是以线程方式在后台运行的,利用空闲时间工做。
5. 操做符重载 Java不支持操做符重载。操做符重载被认为是c++的突出特征,在Java中虽然类大致上能够实现这样的功能,但操做符重载的方便性仍然丢失了很多。Java语言不支持操做符重载是为了保持Java语言尽量简单。
6. 预处理功能 Java不支持预处理功能。c/c++在编译过程当中都有一个预编泽阶段,即众所周知的预处理器。预处理器为开发人员提供了方便,但增长了编译的复杂性。JAVA虚拟机没有预处理器,但它提供的引入语句(import)与c++预处理器的功能相似。
7. Java不支持缺省函数参数,而c++支持 在c中,代码组织在函数中,函数能够访问程序的全局变量。c++增长了类,提供了类算法,该算法是与类相连的函数,c++类方法与Java类方法+分类似,然而,因为c++仍然支持c,因此不能阻止c++开发人员使用函数,结果函数和方法混合使用使得程序比较混乱。Java没有不包含在类中的函数,做为一个比c++更纯的面向对象的语言,Java强迫开发人员把全部例行程序包括在类中,事实上,用方法实现例行程序可激励开发人员更好地组织编码。
8. 字符串 c和c++不支持字符串变量,在c和c++程序中使用Null终止符表明字符串的结束,在Java中字符串是用类对象(strinR和stringBuffer)来实现的,这些类对象是Java语言的核心,用类对象实现字符串有如下几个优势:
(1)在整个系统中创建字符串和访问字符串元素的方法是一致的;
(2)Java字符串类是做为Java语言的一部分定义的,而不是做为外加的延伸部分;
(3)Java字符串执行运行时检空,可帮助排除一些运行时发生的错误;
(4)可对字符串用“+”进行链接操做。
9. goto语句 “可怕”的goto语句是c和c++的“遗物”,它是该语言技术上的合法部分,引用goto语句引发了程序结构的混乱,不易理解,goto语句子要用于无 条件转移子程序和多结构分支技术。鉴于以广理由,Java不提供goto语句,它虽然指定goto做为关键字,但不支持它的使用,使程序简洁易读。
l0. 类型转换 在c和c++中有时出现数据类型的隐含转换,这就涉及了自动强制类型转换问题。例如,在c++中可将一浮点值赋予整型变量,并去掉其尾数。Java不支持c++中的自动强制类型转换,若是须要,必须由程序显式进行强制类型转换。
11. 异常 JAVA中的异常机制用于捕获例外事件,加强系统容错能力
try{//可能产生例外的代码 }catch(exceptionType name){ //处理 }
其中exceptionType表示异常类型。而C++则没有如此方便的机制。