java與c++的區別

2022-07-17 12:00:48

 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速度有了數量級的提高)。