java與c++的區別

 java與c++的區別

提起java就不得不提起jvm,jvm是java得以實現「一次編寫,到處運行」的基礎,也是java相比c++簡單的一大重要原因(GC)這裡就有幾點不同:

跨平台:

  在c++中64位系統下是可以運行32位程序的,但是反過來的話是比較麻煩的。因為32位指針大小為4 byte,而64位的指針大小為8 byte,雖然說本質原因是因為32位系統和64位系統的指針尋址範圍本身就不同。(size_t大法好)

  java就不一樣了,jvm到處都能安,能安就能跑java,虛擬機自己幫忙解決一堆問題,應用極其廣泛。

GC:

  成長在jvm自動GC的環境下的java程序員難以想像c++程序員對內存的瘋狂程度,即使是智能指針的應用也難以磨滅。java對象全部創建在堆上,由jvm負責空間的回收與管理,總的來說是儘可能的分配,不夠了就回頭去找空間可以回收的,用戶完全不用考慮空間回收的問題。c++的對象可以創建在堆上也可以創建在棧上,不加new直創建就是在棧上的,棧快但是空間有限。用new會創建在堆上,C++每一個分配在堆上的空間都必須手動釋放,不然可能會出現內存泄漏等問題。

 

就語言構成來說,java一直被戲稱c++–,在c++中刪除了不少特性,比如:

頭文件:

#include <math.h> => import java.lang.Math;

  在c++中,最終的可執行代碼不包含任何符號信息,因此在使用時(調用庫)需要一個文件來描述代碼使用規則,這就是頭文件。

  而java庫的jar包裏面的內容可以直接讀取,一個 .class 本身兼具了「目標代碼」和「接口定義」的雙重功能,所以不再需要一個單獨的頭文件。(雖然包含類的完整信息,但是對於開發者「不可讀」,因此還需要以文檔的方式提供類的聲明。)

指針:

  java中不需要程序員對指針進行操作。不過這不代表java沒有指針,事實上java的指針操作都被底層代碼封裝了,避免了大量代碼錯誤(c++經典Segmentation fault)。

結構體:

  這個到沒什麼好說的,畢竟c++中struct能實現的class也能實現,就是默認權限不同而已,算精簡語法吧。(不過沒了不使用typedef配合struct來寫結構體而是用class來寫總感覺怪怪的)

運算符重載:

  c++各種重載總能寫出特別魔幻的代碼,同時也是bug之源,java不整這麼花里胡哨的。

union:

  在c++中union主要是共享內存,分配內存以其最大的結構或對象為大小,即sizeof最大的。可以看得出來c++對內存利用的精細程度,位元組級的空間分配,java開發就不用考慮這麼細了。

多重繼承:

  多重繼承可以調用多個基類的不同方法,使代碼更加靈活,同時也變得複雜,而且可能出現菱形繼承的風險。c++一般使用::設定作用域的方式來解決多重繼承中的函數二義性問題。java不支持多重繼承但可以用接口實現,因為接口中的方法,是抽象的,就算一個類實現了多個接口,且這些接口中存在某個同名方法,但是我們要清楚的知道,這個同名方法最終需要由這個類自己來實現,所以並不會出現二義性的問題。

宏:

  java使用final實現類似功能,雖然不像c++中直接字符替換這麼快且應用豐富,但也安全多了。

默認函數參數:

  默認函數參數會影響多態的實現(但可以通過重載實現),c++ 支持默認函數參數,但同時很多編碼規範也禁止在虛方法中使用默認參數。

流:

  java的Stream對象(除了PrintStream)功能較單一,只能按位元組讀寫,需要Reader或者Writer的輔助。C++的任何流都可以按位元組、字符串、整形的方式讀或者寫。另外,Java是少數幾種不能用”==”比較字符串的語言((ΩДΩ)???)。

 

另外,Java為純面向對象語言,所有代碼(包括函數、變量等)必須在類中實現,除基本數據類型(包括int、float等)外,所有類型都是類(第一次見到封裝類的概念都要吐了好吧)。此外,Java語言中不存在全局變量或全局函數,而C++兼具面向對象和面向過程變成的特點,可以定義全局變量和全局函數。就應用方面,java重點面向網絡,c++總的來說還是面向性能。

從根本上來說,Java為解釋性語言,程序源代碼經過Java編譯器編譯成位元組碼,然後由JVM解釋執行。而C/C++為編譯型語言,源代碼經過編譯和鏈接後生成可執行的二進制代碼。因此,Java的執行速度比C/C++慢(即使JIT的引入的確讓Java速度有了數量級的提高)。