Java从诞生起就一直和C++有着密不可分的关系,但是Java和C++之间还是存在着细微的差别的,这些差别一方面体现了Java在优化C++语言方面做出,那么本文就谈谈C++和Java之间那些区别,笔者假设你对C++有一定程度的认识。本文的组织思路是首先是对两者相似的语法规则上进行对比,然后在针对两种语言特有的语法规则进行对比。
1.从数据类型上
Java是一种强类型语言只有八种基本的数据类型,分别是四种整型byte、short、int、long,两种浮点型double、float,一种字符型char,一种布尔型boolean。java的数据类型具有平台无关性,这使得Java语言完美的解决了C++中饱受诟病的可移植性问题。有关C++语言具体的类型知识,
详见博客
。
值得一提的是下面这个例子,
if
(x=
0
);
1
在C++中这种写法虽然不可取,但是并没有违背语法规则,这个表达式一直false。然而Java中这种写法是错误的,这样就避免了潜在的bug,历史上美国电信局曾经因为这个bug造成过严重的损失。
★ java有平台无关性
★java没有long long数据类型
★java不支持if中仅有一个=号
2.在字符串上
①Java中的字符串是不可变的
在Java中,字符串是不可变的,也就说不能单独修改字符串中的一个字符,那么如何修改Java中的字符串呢?举个例子,
String
greet=
"hello"
;
//将greet的后两个字符直接修改为lp!
greet=greet.substring(
0
,
3
)+
"p!"
;
//正确
greet[
3
]=
'p'
;
//错误
123
从这个例子中我们可以看出,刚刚接触Java的C++程序员容易把Java中的String类型误以为为:
String greet[]=
"hello"
;
//这是一种错误的认识
char
* greet=
"hello"
;
//实际上Java中的string更像是这样的,一方面greet的
//
指向是可以修改
的,另一方面不能单独修改单个字符
123
②Java中不能使用==比较字符串
在C++语言中由于重载了==操作符,因此可以直接对字符串进行比较,但是Java中由于采用了不同的机制,这种做法得到的结果并不一定是正确的。这是Java使用常量共享,==仅仅能检测两个字符串是否位于相同的位置,那么Java中如何比较字符串呢?
"hello"
.
equals
(greet);
//C++不能采用这种方法
s
.
equals
(greet);
//s是String类型的变量
12
3.在数组上
①从声明方式
Java数组有两种常见的声明方式:
int
[] a=
new
int
[
100
];
//Java程序猿熟悉这种风格
int
b[];
//数组的维度不必是确定的
12
相比而言,C++的声明方式则是这样的:
int
*a=
new
int
[
100
];
//由程序猿负责内存管理
int
b[
10
];
//数组的维度必须是确定的
12
②Java可以进行数组拷贝,C++则是利用数组的引用或指针的形式实现类似的目的
Java中的是可以直接进行数组拷贝的,例如
int
[] smallPrimes={
2
,
3
,
5
,
7
,
11
,
13
};
int
[] copied=Arrays.copyOf(smallPrimes,smallPrimes.
length
);
12
③从数组遍历上
首先,C++不提供数组下标越界检查,但是Java提供。其次,在数组遍历中两者都提供了简单的数组遍历方法,Java中是for each循环,C++中是范围for语句。
//Java的for each循环遍历二维数组
for
(
double
[] row:a)
for
(
double
value
:row)
do
something with
value
;
//C++范围for语句遍历二维数组
for
(auto &r:a)
for
(auto
value
:r)
do
something with
value
;
12345678
4.从作用域的嵌套规则上
在Java中不允许在嵌套的两个块中声明同名变量
,我们还是通过具体实例来理解:
{
int k;
...
for
(int k=
0
;k<
10
;++k){ //在Java中这种声明方式是错误的
}
}
123456
C++中允许这种声明方式,内层块中的k会屏蔽外层块中的k。
5.Java中没有goto语句
Java中没有goto语句,但是由于Java语言的设计者认为适当使用goto能够为程序带来方便,因此Java语言拓展了原来break语句的功能,使之具有原来C++中类似的功能。
6.Java和C++声明对象上的区别
很多人,会误以为Java中的对象和C++中的引用类似,这样的认识是错误的,但是也是有根源的,我们来看一个例子,
public
class
EmployeeTest
{
public
static
void
main
(String[] args)
{
Employee staff1=
new
Employee();
//注意这也是C++和Java在默认构造函数使用方法的不同之处
Employee staff2=staff1;
staff1.raiseSalary(
0.3
);
//staff1和staff2的salary都将改变
}
}
class Employee
{
//constructor
...
public
Employee
(){...}
public
void
raiseSalary
(
double
byPercent)
{
double
raise = salary * byPercent /
100
;
salary += raise;
}
private
String name;
private
double
salary;
private
Date hireDay;
}
其实Java中的对象更像C++中的指针,这样你对Java中对象的理解就更加方便了
。Java中没有指针的概念
,对象也并不具有C++中指针的全部特性。
staff1和staff2指向相同的内存区域,所以staff1的改变staff2会随之发生改变。
7.C++和Java在对象构造上的区别
①C++和Java在实例域上的区别
C++是不能直接初始化类的实例域(数据域),所有的域必须要直接通过拷贝构造函数进行,但是java是允许直接初始化实例域的,这是因为java中没有子对象,只有指向其他成员的指针。但是C++中有两种数据域是必须要进行直接初始化的,那就是引用和const常量。
②C++和Java在构造函数上的区别
首先,在构造函数的基本形式上,C++和Java是基本一致的,都要声明为共有,都没有返回值,函数名都要与类名保持一致。
在Java中我们有两个地方会用到委托构造的机制,一个是当一个类中存在多个构造函数的时候,我们往往喜欢利用参数少的构造函数来协助完成参数较多的构造函数,例如
public
Employee
(
double
s){
//calls Employee(String,double)
this
(
"Employee #"
+nextId,s);
nextId++;
}
//要使用C++实现同样的功能,表达形式应该是
public
Employee
(
double
s):
Employee
(String,s){
nextId++
789
另一个用到delegate(委托)这种机制的是在类的继承中,子类用到父类(超类)的的构造函数,举个例子,假设Manager是继承自Employee,那么则有
public
Manager
(String n,
double
s,
int
year,
int
month,
int
day){
super
(n,s,month,day);
//注意与上面形式的区别
bonus=
0
;
}
//用C++实现同样的功能,则形式为
Managerr(String n,
double
s,
int
year,
int
month,
int
day):
Employee(n,s,month,day){
bonus=
0
;
}
//当然C++也可以直接对父类的每个数据域进行初始化,而不利用这种形式,但是不提倡。
10
8. C++和Java在虚函数上的区别
总体来说,C++和Java在虚函数上的区别更多的表现在外在形式上,例如Java中是通过在类名之前用
abstract
关键字来声明虚函数,而C++中如果类中函数virtual函数,那么virtual函数所在的类就会被自动声明为虚函数。
9.C++和Java在protected关键字含义上的区别
在Java中,protected关键字是对所有的子类以及同一个package中的所有的其他类可见;在C++中,protected关键字只对子类是可见的。这样看来Java中protected的保护的安全性,比C++要差