1. 程式人生 > >java和C++的區別總結(一)

java和C++的區別總結(一)

  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);

  在C++中這種寫法雖然不可取,但是並沒有違背語法規則,這個表示式一直false。然而Java中這種寫法是錯誤的,這樣就避免了潛在的bug,歷史上美國電信局曾經因為這個bug造成過嚴重的損失。

2.在字串上

①Java中的字串是不可變的

  在Java中,字串是不可變的,也就說不能單獨修改字串中的一個字元,那麼如何修改Java中的字串呢?舉個例子,

String greet="hello";//將greet的後兩個字元直接修改為lp!
greet=greet.substring(0,3)+"p!";//正確
greet[3
]='p';//錯誤

  從這個例子中我們可以看出,剛剛接觸Java的C++程式設計師容易把Java中的String型別誤以為為:

String greet[]="hello";//這是一種錯誤的認識
char* greet="hello";//實際上Java中的string更像是這樣的,一方面greet的
               //指向是可以修改的,另一方面不能單獨修改單個字元

②Java中不能使用==比較字串

  在C++語言中由於過載了==操作符,因此可以直接對字串進行比較,但是Java中由於採用了不同的機制,這種做法得到的結果並不一定是正確的。這是Java使用常量共享,==僅僅能檢測兩個字串是否位於相同的位置,那麼Java中如何比較字串呢?

"hello".equals(greet);//C++不能採用這種方法
s.equals(greet);  //s是String型別的變數 

3.在陣列上

①從宣告方式

  Java陣列有兩種常見的宣告方式:

int[] a=new int[100];//Java程式猿熟悉這種風格
int b[];//陣列的維度不必是確定的

  相比而言,C++的宣告方式則是這樣的:

int *a=new int[100];//由程式猿負責記憶體管理
int b[10];//陣列的維度必須是確定的

②Java可以進行陣列拷貝,C++則是利用陣列的引用或指標的形式實現類似的目的

  Java中的是可以直接進行陣列拷貝的,例如

int[] smallPrimes={2,3,5,7,11,13};
int[] copied=Arrays.copyOf(smallPrimes,smallPrimes.length);

③從陣列遍歷上

  首先,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;

4.從作用域的巢狀規則上

  在Java中不允許在巢狀的兩個塊中宣告同名變數,我們還是通過具體例項來理解:

{
    int k;
    ...
    for(int k=0;k<10;++k){ //在Java中這種宣告方式是錯誤的
    }
}

  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++中指標的全部特性。
Java物件模型
  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++;
}

  另一個用到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++也可以直接對父類的每個資料域進行初始化,而不利用這種形式,但是不提倡。

8. C++和Java在虛擬函式上的區別

  總體來說,C++和Java在虛擬函式上的區別更多的表現在外在形式上,例如Java中是通過在類名之前用abstract關鍵字來宣告虛擬函式,而C++中如果類中函式virtual函式,那麼virtual函式所在的類就會被自動宣告為虛擬函式。

9.C++和Java在protected關鍵字含義上的區別

  在Java中,protected關鍵字是對所有的子類以及同一個package中的所有的其他類可見;在C++中,protected關鍵字只對子類是可見的。這樣看來Java中protected的保護的安全性,比C++要差。