开学这几天读Thinking in Java(新学期教材),正好顺便总结Java相对于C++的一些差异。太明显的语言差异就不写了(比如所有东西都放在类里,没有全局变量之类的)。另外,这不是一个总结Java或C++特性的文章,所以两者当中很多各自独有的特性是没有总结的。,
# 语言特性
- java没有运算符重载。
- 没有goto
- 可以break和continue到某个标签。但是标签后不能跟语句。常用来中断多层循环。
- 增加for each循环
- 没有const关键字,final表示不可更改的量(对基本类型可看作常量,对对象而言则是引用不能指向其他对象,但被指对象是可以修改的)。
- if、for、while等的判断条件中必须使用boolean类型,类似
while(1)
之类的是不允许的。
# 基本数据类型和变量
- Java的char是16位,8位的是byte
- 没有无符号类型
- short、int、liong分别是16、32、64位
- 内部大括号变量名不能覆盖外面同名变量。所以内层大括号不能有和外层变量同名的变量。
- 非基本类型的比较用equals()方法。小心String,Integer这些。
- boolean型不能被转化为其它类型。
- 数组声明时不能指定大小(类似
int a[100];
是不可行的),必须在声明后new出对象时给出new对象的个数,从而给出数组大小(int a[]=new int[100];
)。 - java的数组是一个对象,它持有某种特定类的引用。直接
new 对象[n]
得到的是一个内置n个null引用的对象,若是基本类型则自动为0,多维数组同理。c++相同代码将自动调用无参数的构造函数生成对象。 - 多维数组中同一维上的各个数组可以不等长。C++必须利用指针数组和动态内存分配实现不等长数组。
# 运算符
- 增加无符号右移操作>>>和>>>=,高位补0.
- 没有sizeof(),因为无论什么平台,java的数据类型长度都是一样的。
- 不能在赋值语句里用连续的逗号(如:a=1,2,3;)。而且不能用逗号分开语句。
# 对象初始化和清除
- 不支持构造函数的初始化列表(但是可以把类内部对象的初始化代码看作初始化列表)。
- Java自己的构造方法调用自身其他构造方法必须以:
this(参数列表);
的方式调用,且必须在构造方法开始处。C++只需:new (this)类名(参数列表);
就可以调用,且位置随意。 - 静态方法调用是:类名.方法, 而C++则是:类名::方法。
- Java类内有static代码块。里面内容只执行1次,在该类第一个对象生成或首次访问其静态成员时执行。
- java类内非static代码快在对象被new出来时执行,C++类内部不能写代码。所以java非static代码块可在任意处。
- java的static成员在类内直接指定初始化值,C++的static成员在类外和main外的全局区域(类型名 类名::static成员名=xxx)。
- java的方法内不能有静态变量(和内存布局有关,静态变量在data区,而方法内的属于栈区,只能存放基本类型和引用,见链接)
- java可以在类的定义里为变量赋初值,C++不行。
- Java会把类定义里变量赋初值工作放在类的代码最前面(在构造方法调用前就执行)。且初始化顺序和定义顺序相同。
# 类特性
- 增加反射机制
- 没有多重继承(但可以实现多个接口类,或者用多个内部类替代)
- Java的内部类定义位置随意,C++的必须把内部类定义放在使用内部类之前的地方。
- java的static成员只能new被static修饰的内部类,C++没有static内部类,static方法可以直接new内部类。
- C++内部类不能直接访问外部类的成员。但java可以。
- 没有友元
- 只有公共继承(extends关键字)
- 基类方法被重载后,如果在子类中重新定义这个方法不会屏蔽任何一个在基类中的版本。
- java类内的protected成员可以被同一个包内的类访问。C++类的protected成员不能被一个名字空间的类访问。所以名字空间=包的想法是不对的。
- 增加final关键字阻止覆盖方法。被指定为final的类型不能被继承。
- 重写方法自动是动态绑定的,不像C++需要virtual关键字。
- java向下转型会检查对象实际是不是被转到的类型。C++不检查。
- 增加abstract关键字,修饰方法(等价于C++纯虚函数),修饰类(这种类含有abstract方法,等价于C++抽象类)。
- 增加接口(Interface),但是接口无构造方法,接口内方法自动为public,且内部变量自动为static。C++纯虚类可以有构造方法,非静态成员等等。
# 异常处理
- C++没有finally关键字
- C++可以throw和函数的异常说明列表不同的异常,java则必须抛出和异常说明表相同的异常。
- 两者都可以在main里抛出异常,但C++的main不能有throw列表。
# 泛型
- java的泛型参数类型不能为基本类型。
- 定义java的泛型函数(方法)的泛型参数列表要放在返回值之前。C++需要用
template<class T>
- 对函数(方法)显示地进行类型说明时:java在 . 操作符和方法之间插入尖括号说明(类内部用this.),C++是在方法名和参数列表之间放尖括号。
- java的父类容器存放子类,可以从容器中取出对象调用子类方法,C++的STL容器中始终调用父类方法(甚至用虚函数也是)。
- Java在泛型代码内部无法获得任何有关泛型参数的类型信息。
- Java中,若泛型参数为T,不能new T()。原因见上一条。
- java中增加了C++没有的通配符‘?’(注意? super 和? extends的用法)。
# 其它
- java的String是不可变的,C++的string可变。
以上只是初步的总结,如果总结的有问题请留下评论。大概以后还会更新这篇文章。