Java VS C++

來源:互聯網
上載者:User

JAVA和C++都是物件導向語言。也就是說,它們都能夠實現物件導向思想(封裝,繼乘,多態)。而由於c++為了照顧大量的C語言使用者,而相容了C,使得自身僅僅成為了帶類的C語言,多多少少影響了其物件導向的徹底性!JAVA則是完全的物件導向語言,它句法更清晰,規模更小,更易學。它是在對多種程式設計語言進行了深入細緻研究的基礎上,摒棄了其他語言的不足之處,從根本上解決了c++的固有缺陷。

Java和c++的相似之處多於不同之處,但兩種語言有幾處主要的不同使得Java更容易學習,並且編程環境更為簡單。

我在這裡不能完全列出不同之處,僅列出比較顯著的區別:

1.指標

JAVA語言讓編程者無法找到指標來直接存取記憶體無指標,並且增添了自動的記憶體管理功能,從而有效地防止了c/c++語言中指標操作失誤,如野指標所造成的系統崩潰。但也不是說JAVA沒有指標,虛擬機器內部還是使用了指標,只是外人不得使用而已。這有利於Java程式的安全。

2.多重繼承

c++支援多重繼承,這是c++的一個特徵,它允許多父類派生一個類。儘管多重繼承功能很強,但使用複雜,而且會引起許多麻煩,編譯器實現它也很不容易。Java不支援多重繼承,但允許一個類繼承多個介面(extends+implement),實現了c++多重繼承的功能,又避免了c++中的多重繼承實現方式帶來的諸多不便。

3.資料類型及類

Java是完全物件導向的語言,所有函數和變數都必須是類的一部分。除了基礎資料型別 (Elementary Data Type)之外,其餘的都作為類對象,包括數組。對象將資料和方法結合起來,把它們封裝在類中,這樣每個對象都可實現自己的特點和行為。而c++允許將函數和變數定義為全域的。此外,Java中取消了c/c++中的結構和聯合,消除了不必要的麻煩。

4.自動記憶體管理

Java程式中所有的對象都是用new操作符建立在記憶體堆棧上,這個操作符類似於c++的new操作符。下面的語句由一個建立了一個類Read的對象,然後調用該對象的work方法:

Read r=new Read();
r.work();
 

語句Read r=new Read();在堆棧結構上建立了一個Read的執行個體。Java自動進行無用記憶體回收操作,不需要程式員進行刪除。而c十十中必須由程式員釋放記憶體資源,增加了程式設計者的負擔。Java中當一個對象不被再用到時,無用記憶體回收器將給它加上標籤以示刪除。JAVA裡無用記憶體回收程式是以線程方式在後台啟動並執行,利用空閑時間工作。

5.操作符重載

Java不支援操作符重載。操作符重載被認為是c十十的突出特徵,在Java中雖然類大體上可以實現這樣的功能,但操作符重載的方便性仍然丟失了不少。Java語言不支援操作符重載是為了保持Java語言儘可能簡單。

6.預先處理功能

Java不支援預先處理功能。c/c十十在編譯過程中都有一個預編澤階段,即眾所周知的前置處理器。前置處理器為開發人員提供了方便,但增加了編譯的複雜性。JAVA虛擬機器沒有前置處理器,但它提供的引入語句(import)與c十十前置處理器的功能類似。

7. Java不支援預設函數參數,而c十十支援

在c中,程式碼群組織在函數中,函數可以訪問程式的全域變數。c十十增加了類,提供了類演算法,該演算法是與類相連的函數,c十十類方法與Java類方法十分相似,然而,由於c十十仍然支援c,所以不能阻止c十十開發人員使用函數,結果函數和方法混合使用使得程式比較混亂。

Java沒有函數,作為一個比c十十更純的物件導向的語言,Java強迫開發人員把所有例行程式包括在類中,事實上,用方法實現例行程式可激勵開發人員更好地組織編碼。

8 字串

c和c十十不支援字串變數,在c和c十十程式中使用Null終止符代表字串的結束,在Java中字串是用類對象(string和stringBuffer)來實現的,這些類對象是Java語言的核心,用類對象實現字串有以下幾個優點:

(1)在整個系統中建立字串和訪問字串元素的方法是一致的;

(2)J3陽字串類是作為Java語言的一部分定義的,而不是作為外加的延伸部分;

(3)Java字串執行運行時檢空,可協助排除一些運行時發生的錯誤;

(4)可對字串用“十”進行串連操作。

9“goto語句

“可怕”的goto語句是c和c++的“遺物”,它是該語言技術上的合法部分,引用goto語句引起了程式結構的混亂,不易理解,goto語句子要用於無條件轉移子程式和多結構分支技術。鑒於以廣理由,Java不提供goto語句,它雖然指定goto作為關鍵字,但不支援它的使用,使程式簡潔易讀。

l0.類型轉換

在c和c十十中有時出現資料類型的隱含轉換,這就涉及了自動強制類型轉換問題。例如,在c十十中可將一浮點值賦予整型變數,並去掉其尾數。Java不支援c十十中的自動強制類型轉換,如果需要,必須由程式顯式進行強制類型轉換。

11.異常

JAVA中的異常機制用於捕獲例外事件,增強系統容錯能力

try{//可能產生例外的代碼
}catch(exceptionType name){
//處理
}
 

 

其中exceptionType表示異常類型。而C++則沒有如此方便的機制。

 

附:

Java群體每天都在擴大,它既包括一些世界最大的ISV,也包括公司CIO、資訊技術人員、系統分析人員、C/S開發人員、編程人員、多媒體設計者、市場行銷人員、教育工作者、經理、影視生產者甚至業餘愛好者等廣泛的使用者。從傳統上看,這樣一些人在一起有效地工作是不多見的。當我們談到開放系統時,我們往往是就已發表的API及規格,或者源碼的可得性,或者硬體、連網及作業系統而言的,沒有一個人是從人的開放意義上來談的。Java完成了開放系統的閉合鏈。它開發了人力資源,而反過來又開闢了共同工作的道路。

一談到Java,人們馬上會想起一種類似於C++的、適用於分布環境的物件導向程式設計語言,想到這種語言的簡單、穩定、安全、與體繫結構無關、可移植、可解釋、高效能、多線程和動態性等特徵。這些都是Java作為一種程式設計語言的主要特徵。

Java是由Sun公司的一個技術小組研製出來的。在實現Java語言的過程中,Sun小組的技術人員很快就意識到:C++無法成為一種完全物件導向的、網路化的開發語言。C++是通過給原先的C語言增加物件導向功能而開發出來的,因此,它存在著先天不足。這主要體現在C++種類繁多,功能大量冗餘,同時又沒有任何一種C++編譯器能夠支援它的全部功能。鑒於這種情況,Sun公司的技術人員決定不擴充C++,而開發一種全新的電腦語言(Java的前身Oak)。但是,C++已經成了大多數編程人員所熟練掌握的語言,Java的設計顯然不能無視這個現實。如果Java和C++之間的差別過大,那麼程式員們在學會這種語言的過程中無疑要花費大量的時間和精力。因此,Java保留了儘可能多的C++風格。

Java自誕生起,為網路使用者創造了無數用戶端的小應用程式,由於這類應用程式效果良好、數量巨大,以至於許多使用者想到Java程式設計語言時,會在腦海中出現一個不完全正確的印象-Java是用來編寫小的用戶端程式的。其實,隨著技術的進步,Java語言正在逐步改變自己執行效率較低、無法擔任企業關鍵計算任務的形象,不斷向計算技術的核心地帶前進。今天的Java技術正沿著網路滲入各個應用領域。

企業計算:企業計算是Java最重要的技術主題。Sun公司已經公布了企業JavaBean(EJB,Enterprise JavaBean)的規格,隨後眾多公司開始開發公司專屬應用程式領域的Java技術。IBM公司也已經為Windows NT開發了IBM HPCJ(High Performance Compiler for Java)12.0版,同時研製了IBM JDK(JavaDevelopment Kit)for Windows NT,Novell公司也在宣布了一個新的伺服器端的企業Java平台,而Sun公司也在積極地升級自己的JDK系統,這個形勢表明,Java正在穩步走向企業高端計算。對於Java來說,與其它程式設計語言爭奪企業計算主力編程工具的優勢在於:其一,Java在進行物件導向的編程工作時,比其它的程式設計語言如C++更加簡單,因此保證了編程的高效率,減少了編程投入;其二,Java虛擬機器技術所提供的"一次編程,到處使用"的跨平台能力非常適合網路環境,這給Java在網路伺服器端的發展提供了便利條件;其三,Java擁有強大的供應商和支援者隊伍,該隊伍包括IBM、Oracle、Novell、Sybase和Netscape等公司。

提速運行:許多企業的應用開發人員非常喜愛Java的語言特性,但是在開發重要系統時,語言特性和執行效率之間的抉擇往往令人傷透腦筋。在關鍵計算中,使用者可能並不在乎資料如何壓縮或者啟動並執行延遲關係如何設定,但是對程式的運行速度卻非常重視,這使廠商將Java的編譯策略開發放在了首位。現在的Java語言,其執行方式已經不僅僅是解釋執行方式了,即時編譯器(JITC、just-in-time compiler)技術和原型編譯技術已經被許多廠家採用,包括Sun、IBM、Oracle以及Netscape等公司在內的技術供應商正在利用這些技術逐步提高Java的執行速度,其中IBM公司早已將Java虛擬機器(JVM,JavaVirtual Machine)、作業系統和硬體的特性有機的結合在一起,非常有效地提高了Java的執行效率。

嵌入計算:嵌入式Java是一個潛力巨大的應用技術,該技術充分發揮了Java小巧靈活的特點。以HP公司為例,該公司以自己的方式製造編譯工具和Java虛擬機器,其目的是將Java嵌入各種裝置,如印表機、醫學監視器和自動提款機等。嵌入裝置依靠一個即時作業系統來處理某一個即時生效的事件,Java被嵌入這些裝置後,通過即時擴充(real-time extension)開始發揮作用,使裝置具備了一定的智能性,增強了嵌入裝置的可管理性和可用性,大大提高了裝置的工作效率。各廠商對這一潛力巨大的市場都非常重視,目前該市場缺乏的是一個標準,如果存在標準的話,相信很快就會有大量使用嵌入Java技術的裝置上市。

微軟剛剛發行的Windows XP放棄了對Java的支援,但Java能夠獨立運行於很多操作平台上,其中也包括Linux,並且在某些特性上要比在Windows上發揮得更好,我們完全有理由拋棄Windows而選擇使用Linux來做Java開發。現在,你可以左手拿著Linux,右手拿著Java,然後對面帶微笑手裡拿著Windows XP的Bill Gates說:"讓你的XP去見鬼吧!"

對於軟體開發人員來講,任何一種程式設計語言都不可能是完美的。如果希望更好地理解Java語言,最好的方法是把這種語言與其同類型的語言相比較。既然Java類似於C++,把它同C++進行一番比較也是順理成章的事情,哪一個好,哪一個不好,每個開發人員都有各自的看法。我個人認為Java開發要比C++好一些。當然每個人的看法和喜好是不同的。後面的文章將向大家介紹Java和C++的不同和對其的改進。孰強孰弱,大家自然就會明白了。

我們知道,Java一開始採用C++的文法格式,基本上是為了讓程式設計者可以很快地熟悉 Java的文法格式,縮短學習Java的時間,畢竟C和C++仍舊是最多人會的一種程式語言。但是如果我們仔細檢查Java程式語言的許多細節設計,我們可以發現Java去掉了不少C++的特點,並且加入一些新的特性。這些與C++的差異包括:

1.不再有#define、#include等預先處理程式(Preprocessor)的功能

C++語言很重要的一個特點就是它的預先處理程式。有些其他程式語言雖然也加入了#include的功能,但是還是欠缺處理宏(Macro)的能力。#define的功能在Java中我們可以用定義常數(constant)的方式來取代,而#include在Java中是不需要的,因為在Java中程式在執行時,會把類型資料記錄在對象實體之中,我們不需要靠一些標題檔案(header file)來知道我們使用的對象或數值是屬於什麼資料類型。

如果你使用C++語言時,只使用預先處理程式的#include和#define功能的話,那麼你大概不會覺得Java這樣的設計對你產生什麼樣的困擾,但是如果你是使用C++語言預先處理程式中宏功能的高手,你可能會覺得很不方便,進而懷疑Java如此設計的意義何在。

使用預先處理程式雖然可以很方便地達到許多功能,但是站在軟體工程的角度上看,對整個軟體的維護其實是很不利的。由於C++語言中預先處理程式的功能太過強大,厲害的程式設計高手常會自行開發一套只有自己看的懂的宏語言,一旦整個軟體要交給其他人去維護,後繼者很難在短時間內瞭解前一個人所寫下的宏功能,增加軟體開發時團隊工作及日後維護的困難度。

另外一點則是C++語言的編譯器所看到的程式碼,其實和程式設計者看到的程式碼是不同的。程式設計者看到的是尚未經過預先處理程式處理過的程式碼,而編譯器看到的則是預先處理程式處理過的程式碼,一旦交給預先處理程式處理的宏內容有誤,編譯器產生的錯誤資訊將不會是程式設計師所預料的。而這一點自然也增加了程式在排錯時的困難度。

預先處理程式的存在也造成了閱讀程式的不便。如果你想使用別人已經完成的C++語言程式,那麼通常你不但要閱讀他所寫下的檔案,還必須一併查閱上檔案,才能瞭解其程式的全貌。如果換成是Java程式,只要查看java的程式檔案就夠了。

2.不再有structure、union及typedef

事實上,早在C++中就可以去掉C語言中的structure和union等對複雜資料的自定結構類型,因為類(Class)的定義方式可以完全做到這項功能。而typedef也是不必要的,一切都用類就可以了。雖然C++這樣的設計是為了和C語言相容,但是使用多餘的語言特點不但不必要,而且容易造成對程式認識的混淆。

3.不再有函數

在Java程式語言中,去掉了程式嚮導語言中最重要的單元--函數(Function)。如果我們以對象嚮導的觀念來看待函數,就可以瞭解函數在對象嚮導的概念中,是不必要的。在對象嚮導的程式觀念裡,對象的資料才是真正的主體,而處理對象資料的方法則必須依附在對象內才有意義。因此,去掉函數並不表示不再有子程式等模組化程 序的概念,相反地,是利用對象中的方法來取代函數,再一次強化對嚮導的發展策略。

4.不再有多重繼承(Multiplelnheritance)

在C++中,多重繼承是一項很強的功能,但也是一般人難以掌控的部分。去掉多重繼承雖然降低了Java語言的功能,但是也大幅簡化撰寫程式時的困難度。雖然移除了多重繼承的功能,但是Java提供了interface的方式,可以達到部分多重繼承的功用。所謂的interface基本上定義了一個類的對外溝通的方法原型,以及類內部的常 數,和多重繼承不同之處在於interface並不會定義類方法的內容,以及類中的變數資料。

5.不再有Goto

在程式語言的發展史上,Goto一直是毀譽參半的一項功能。在很多時候使用Goto可以大幅減少不必要的程式碼,但是也由於Goto可以很自由地改變程式的流程,如果冒然地使用,更可能造成程式結構混亂的情況。一般來說,正確使用Goto的例子多出現在迴圈內部,想要提早結束某一層迴圈。在C語言中,我們可以使用break 或contine來改變某一層迴圈的流程, 但如果想要改變兩層以上的環執行流程,不是使用Goto就是以多餘的布爾(boolean)變數,配合上一串if-then-else的判斷來達成。

Java一方面移除了Goto的功能, 而另一方面同時擴大了break和continue的功能,可以允許多層迴圈的break或continue。如此一來不但避免了濫用Goto的可能性,同時也儲存下Goto的好處。

6.不再有OperatorOverloading

在C++中,Operator Overloading同樣也是一項值得討論的設計。幾乎在所有C++的書中,都會引用一些例子,告訴你使用OperatorOverloading可以使你的程式看起來更為自然。如下面是一個程式設計師自訂的複數類:

//C++中自訂的複數類及0pemtor Overloading
class Complex{
public:
Complex(double real,double image){
Real_number=real;
Image_number=image;
}
Complex operator+(Complex&rhs){
Return Complex(rhs.real_number+real_number,
rhs.image_number+image_,nulnbef);
}
private:
doublereal_number //實部
doublejmage_nunmber; //虛部
}

 

在這裡,如果你使用+來作為複數的加法符號,大家都不會有疑義,但是如果你使用的是*或》這樣的符號,那麼別人看到你的程式之後,難保不會產生認識上的錯誤。這也是Operator Overloading一大問題,當大家都對運算子賦予自己的定義後,整個程式的可讀性就會大受影響。Operator Overloading的存在並不是必要的,我們一樣可以定義類中的方法來達到同樣的目的,至於Java去掉這項功能的利弊,恐怕就要讀者自己去評斷了。

7.取消自動類型轉換

Java是一個嚴格進行類型檢查的程式語言,對於下面這樣的程式,在C++的編譯器上編譯時間最多隻會出現警告的資訊,但是在Java裡則不予通過:

Int aInteger; Double aDouble=2.71828; AInteger = aDouble;

雖然這樣的轉型在C++裡是合法的,但是也會造成資料精確度的損失。Java為了要確定寫程式的人充分地瞭解這點,必須要程式設計強制轉型(type casting),Java的編譯器才會接受:

int aInteger;
doublea Double=2.71828;
aInteger=(int)aDouble;

 

8.不再有指標

取消指標(Pointer)這樣資料類型,可能會讓許多熟悉C++語言的程式設計師大吃一驚。在C++語言裡,靈活地運用指標是許多程式設計師的得意之作,但是占整個除錯時間最久的也是指標的問題。配合上C++對記憶體管理的態度,程式設計師必須要自己去追蹤自己向系統要到的記憶體,最後確實地交還給系統,並且在使用指標時,要小心翼翼地注意不要跨過合法的記憶空間,造成Segmentation Fault或General Protection Fault之類的問題。

Java去掉了指標類型,並不表示程式設計師在開發進階資料結構,像堆棧(stack)、 隊列(queue)、二元樹(binarytree)時,都必須要像在傳統Basic上,利用大範圍的數組來自行類比系統記憶體,自行建構類似指標的表示方式。

相反地,Java提供了和Lisp語言中相似的Reference類型,通過Reference去讀取配置到的記憶體內容,可以確保不會去讀取到不屬於自己的記憶體空間,而另一方面,程式的執行系統也可以動態地去做記憶體記憶體回收的工作,將沒有被reference參考到的記憶體空間回收給系統使用。

9.和C++串連

不管Java是多麼強大,總是有人需要把它和C++串連起來。因為只要有一個新的程式語言或是軟體開發工具一出現,大家就會問:"它是否具有和原有程式庫串連的能力呢?"也因為C++語言在電腦界中佔了很重要的地位。大家的問題其實就等於是直接問"它是否可以和C++串連?"。目前在Java中,的確提供了和C++語言串連的方法,它的做法基本上是先將C++語言所寫的程式建構成動態連結函數庫(DynamicLinking Library,DLL),再由Java程式去調用DLL裡的函數。

這種串連的方式,使得DLL中的函數,從Java的眼光看就是一個"方法"。不過因為這種方法是直接由其他的程式語言所提供,而不是以Java語言所寫的,所以它被稱之為"原生方法"(NativeMethod)。

由於Java Applet一些安全上的限制,所以這種串連外部程式的方法只能用在Java Application內。

小結:

事實上,constant和typedef這兩條語句包含了#define語句的作用。現在,結構和聯合已經被Java的類所代替。刪除這些特性的原因是:由於其希望維持與C語言的向後相容性,C ++的語言規範包含了大量冗餘。比如,類實際上就已經包括了結構和聯合的作用,因此這兩種資料結構完全可以取消。關於#define語句,Java語言規範的制訂者認為:儘管該語句的出發點是為了增強程式的可讀性,但實際效果卻恰恰相反,它常常導致難讀的代碼,故應該予以取消。Java不再支援獨立函數,因此任何函數都必須封裝到某個類中。由於人們普遍認為, C++所用的超類是非常不穩定的,因此Java拋棄了C++中的多繼承並代之以介面。Java的介面指的是,在別的類看來一個類所能實現的方法。它所顯示的只是一個類的方法或常量和變數 ,而不是這個類的全部結構。

最後,Java還取消了C++中的GOTO語句、操作符重載、自動類型轉換及指標資料類型。 GOTO語句引起的爭議已經有很多年了,可一直陰魂不散,這跟某些程式員對該語句一直情有獨鐘有關。C++仍然支援資料類型的自動轉換,但Java要求編程人員顯式實現資料類型之間的轉換。自動資料類型轉換使得兩個資料類型互不相容的變數可以相互賦值,而不需要給出顯式說明。這有時會導致一些問題,其中最常見的是精確度損失。比方說,如果把一個帶符號的32位整數賦給一個不帶正負號的整數,則所有的結果均為正數。Java的設計者們認為這很容易引起程式錯誤,從而決定不支援這種轉換方式。

【FROM】http://zhidao.baidu.com/question/96662104.html?si=8

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.