日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

比较C#和Java

發(fā)布時間:2025/3/21 C# 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 比较C#和Java 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文對比C#與Java編程語言。 因為這兩種語言都具有自動垃圾回收以及運行時編譯執(zhí)行的特點,并且他們的語法都是繼承自C語言/C++,因此二者有很多相似之處。

但由于C#也被描述為一個C++和Java的混合體,并添加了一些新特性,引入了一些變化,因此C#和Java自然也有很多不一樣的地方。

這個條目描述了二者總體上的相似性,并列舉了二者的不同點。

?

目錄

  • 1語言
    • 1.1對象處理
      • 1.1.1引用
    • 1.2數(shù)據(jù)類型
      • 1.2.1數(shù)組
      • 1.2.2內(nèi)部類
      • 1.2.3部分類
      • 1.2.4泛型
    • 1.3符號和特殊功能
      • 1.3.1特殊功能關(guān)鍵字
      • 1.3.2回調(diào)和事件處理
    • 1.4數(shù)值應(yīng)用
      • 1.4.1運算符重載
    • 1.5方法
      • 1.5.1顯式接口實現(xiàn)
      • 1.5.2開包
      • 1.5.3Lambdas和表達樹
      • 1.5.4部分方法
      • 1.5.5擴展方法
      • 1.5.6發(fā)生器方法
    • 1.6條件編譯
    • 1.7名字空間和源文件
    • 1.8異常處理
      • 1.8.1Finally塊和未捕捉的異常
    • 1.9底層的代碼
  • 2參考文獻
  • 3外部鏈接

語言[編輯]

對象處理[編輯]

C#和Java都被設(shè)計成一個使用動態(tài)調(diào)度的類似于C++語法的完全的面向?qū)ο笳Z言。(C++又是源自于C)。但是,這兩種語言都不是c或者c++的一個擴展集。C#和Java都使用垃圾回收作為一種回收內(nèi)存資源的手段,而不是直接的釋放內(nèi)存。C#和Java都包含線程同步機制作為他們語法的一部分。

引用[編輯]

C#允許指針的有限功能的使用,指針和運算指針在一個操作的環(huán)境中是存在潛在的不安全性的,因為他們的使用可以避開對象的一些嚴(yán)格訪問規(guī)則。C#中使用指針的代碼段或者方法的地址要用unsafe關(guān)鍵字進行標(biāo)記,這樣,這些代碼的使用者就會知道這個代碼相比其他的代碼而言是不具有安全性的。編譯器需要unsafe關(guān)鍵字時將使用此代碼的程序轉(zhuǎn)換成是允許被編譯的。一般來說,不安全代碼的使用可能是為了非托管的API(應(yīng)用程序編程接口)的更好互用,或者是為了(存在內(nèi)在不安全性的)系統(tǒng)調(diào)用,也有可能是出于提高性能等方面的原因。而Java中不允許指針或者算術(shù)指針的使用。

數(shù)據(jù)類型[編輯]

java和C#語言都有原始數(shù)據(jù)類型的概念,C#/.NET語言中支持的原始數(shù)據(jù)(所有的,除了string類型)都是值類型。但C#比java支持更多的原始數(shù)據(jù)類型,比如整型和十進制浮點數(shù),尤其是java缺少無符號的BYTE類型,而C#的BYTE類型默認(rèn)是無符號的。在兩種語言中string其值都是不可改變的一個類,但是特殊的是C#為其提供了特殊的構(gòu)造方法,同時C#還可以像值類型一樣的使用string的值就而不需要進行拆箱操作。 既允許自動裝箱和拆箱,把它們從對象類型轉(zhuǎn)換為原始數(shù)據(jù)。實際上,這使得原始類型成為對象類型的子類型。在C#中這也意味著,原始類型可以定義方法,如覆蓋的對象的ToString()的方法。在Java中,單獨的原始包裝類提供這種功能。在Java中原始值不含隱式裝箱和一個顯示的類型轉(zhuǎn)換都需要一個實例稱為原始值的((Integer)42).toString()而不是C#中調(diào)用實例 42.ToString()。另一個不同之處在于,java使大量使用裝箱類型(見下文),這樣可以讓一個隱式拆箱轉(zhuǎn)換(在C #這需要一個類型轉(zhuǎn)換)。由于這些隱性拆箱轉(zhuǎn)換可能會拋出空指針例外,現(xiàn)代集成開發(fā)環(huán)境和編譯器可以配置為突出它們。 值類型 C#允許程序員用關(guān)鍵字struct創(chuàng)建用戶自定義的值類型(value type)。 從程序員的角度來講,它們可以被看做輕量級的類。

不同于一般類,而像標(biāo)準(zhǔn)基本類,這種值類型被分配在棧內(nèi)存(stack)而不是堆內(nèi)存(heap)。 結(jié)構(gòu)體通常有一系列的限制,因為結(jié)構(gòu)體沒有空值的概念并且可以在數(shù)組中無需初始化而直接使用,這種類型也有必須用0來初始化內(nèi)存空間的默認(rèn)構(gòu)造函數(shù)。 程序員只能定義另外的帶有一個或多個參數(shù)的構(gòu)造函數(shù)。

這也意味著結(jié)構(gòu)體缺少一個虛方法表,正因為這樣(還有固定的內(nèi)存空間),它們不允許繼承(但可以實現(xiàn)接口)。

數(shù)組[編輯]

數(shù)組和集合類同樣在語法中給出了重要意義,感謝基于迭代器的預(yù)聲明循環(huán)。在C#里一個數(shù)組反映為一個數(shù)組類的對象,而在JAVA每個數(shù)組都是一個直接的對象集的子集(但是可以映射為一個以它真正的成員類為父類的一個數(shù)組),并且不實現(xiàn)任何的集合界面。C#擁有真正的多維數(shù)組,如同Java中可用到的數(shù)組的數(shù)組(在C#中通常稱為鋸齒數(shù)組)。多維數(shù)組可以因為增強位置(就像有一個單一的指示器解除參照,代替數(shù)組的每一維作為鋸齒數(shù)組的容器)在某些情況下增強性能。另一個優(yōu)點是整個多維數(shù)組可以用單一的new操作符申請而賦值,而鋸齒數(shù)組需要對每一維進行循環(huán)和賦值。注意,盡管Java為分配多維的鋸齒數(shù)組提供依據(jù)句法的整齊的數(shù)組長度(在C#術(shù)語中是一個矩形數(shù)組),循環(huán)和多樣的分配被虛擬機完成不需要外在的來源。

內(nèi)部類[編輯]

java與C#都允許設(shè)置內(nèi)部類,即在一個類內(nèi)部定義的另一個類。在java中,這些內(nèi)部類可以訪問外部類的靜態(tài)和非靜態(tài)成員(除非這個內(nèi)部類定義為靜態(tài)的,在這種情況下只能訪問外部類的靜態(tài)成員)。局部內(nèi)部類可以定義在一個方法中并訪問這個方法中聲明為final類型的局部變量,匿名局部類允許構(gòu)造類的實例用來重寫類的方法。

C#也提供內(nèi)部類,與Java不同的是它需要外部類的非靜態(tài)成員的一個明確引用。同時C#提供匿名類作為一個結(jié)構(gòu)用來訪問局部變量和方法(參見事件處理)。局部類和匿名類不能被訪問。

部分類[編輯]

C#使用部分類允許一個類的定義分割在幾個源文件中。每一個部分必須用關(guān)鍵字partial標(biāo)記。作為一個單一的匯編的部分所有的部分都必須提交給編譯器。每個部分可以引用其它部分的成員。每個部分都可以實現(xiàn)接口,并且某個部分可以定義一個基類。這個功能在代碼生成時非常有用,也就是一個代碼發(fā)生器提供一部分代碼,開發(fā)商提供另一部分代碼,兩種代碼在一起編譯。因此開發(fā)商可以編輯他們的部分代碼而不用冒著代碼發(fā)生器在以后覆蓋這部分代碼的危險。和類擴展機制不同,部分類在它的部分之間允許循環(huán)依賴,因為它們在編譯的時候都保證被解決。Java沒有類似的概念。

泛型[編輯]

泛型編程

現(xiàn)在的編程語言都支持泛型編程,但它們卻采用了不同的實現(xiàn)方式。

Java中的泛型僅是語言層面上的一種結(jié)構(gòu),它們只能通過編譯器來實現(xiàn)。生成的類文件中所包含的類簽名僅由元數(shù)據(jù)組成(允許編譯器對這些新類進行反編譯)。運行時并不知道通用類型系統(tǒng),這意味著JVM只需要進行一小部分的更新便可處理新的類格式。

為了實現(xiàn)這個目標(biāo),編譯器用泛型類型的上界來替換它們,并且在用到這些泛型的各個地方適當(dāng)?shù)夭迦胍恍敖巧薄=Y(jié)果生成的字節(jié)碼將不包含任何對這些泛型類型的引用或?qū)⑺鼈冏鳛閰?shù)。這種實現(xiàn)泛型的技術(shù)被稱作類型擦除。這意味著實際上的類型的信息在運行時不可用,并且強行加入了一些限制,例如不能創(chuàng)建泛型的新實例或數(shù)組。(參見Java中的泛型)。

C#采用了另一種實現(xiàn)方式。它對泛型的支持是集成在虛擬執(zhí)行系統(tǒng)中的,并且最早出現(xiàn)在.NET2.0中。這門語言后來就發(fā)展為在執(zhí)行系統(tǒng)中支持基本泛型的前端。而在Java中,編譯器提供了靜態(tài)類型安全檢查,但是,加之又有即時編譯器(JIT)加載來核實其正確性。關(guān)于泛型類型的信息在運行時完全被保護起來了,并且允許完全的反射和實例化泛型類型。

Java不允許用基本數(shù)據(jù)類型來聲明為泛型類,然而C#卻允許不管是引用類型還是值類型被聲明為泛型,包括基本數(shù)據(jù)類型。Java卻允許被封裝的類型作為泛型類的類型參數(shù)來使用(例如:用List<Integer>代替List<int>),但是由于所有這一類的值需要在堆上分配而需付出一定的“代價”。 在Java和C#兩者中,泛型的定義都使用了不同的引用類型來分享等效的底層代碼,但是對C#來說公共語言運行時(CLR)為值類型的實例化動態(tài)的生成優(yōu)化代碼。

符號和特殊功能[編輯]

特殊功能關(guān)鍵字[編輯]

關(guān)鍵字功能,實例
checked,?unchecked在C#里,?checked?聲明塊或表達式可以在運行時檢查算術(shù)的溢出。
get,?setC#實現(xiàn)屬性作為語言語法的一部分,而且選用相應(yīng)的get?和set?訪問器, 而Java的訪問方法, 不是一種語言功能,而是基于方法命名公約的編碼方式。
gotoC#中支持goto關(guān)鍵字。goto有時候是有用的, 舉個例子,實現(xiàn)有限的狀態(tài)機或者生成的代碼, 但是通常建議使用更加合理控制流程的結(jié)構(gòu)化方法(見goto語句的評論)。 Java 允許使用breaks和continues彌補了goto語句的的許多用途。 switch(color) {case Color.Blue:Console.WriteLine("Color is blue"); break;case Color.DarkBlue:Console.WriteLine("Color is dark");goto case Color.Blue;// ... }
out,?refC#支持輸出參數(shù)和引用參數(shù)。這使得c#可以從一個方法返回多個值或者通過引用傳遞多個值。
strictfpJava 使用關(guān)鍵字?strictfp?確保跨平臺時浮點運算的結(jié)果保持不變。
switch在C#里, switch 語句也操作于string型和long型,但是只允許失敗的空白語句。 Java switch 語句在Java7之后才支援操作strings;不能操作于long?的原始類型 但是能通過所有的空白語句(不包括那些含有 'break'的語句)。
throwsJava中要求每個方法都要聲明它能拋出檢測異常或者檢測異常的父類。任何方法也可以隨意的定義它所拋出的非檢測異常,C#中卻沒有這樣的語法規(guī)則。 public int readItem() throws java.io.IOException {// ... }
usingC#中的using指令使得對象的Dispose方法(通過IDisposable接口被執(zhí)行)定義為在代碼塊執(zhí)行之后或者在代碼塊之中的異常被拋出時才被執(zhí)行。 //創(chuàng)建一個小文件"test.txt",寫一個字符串, //... 并且把它關(guān)閉(即使發(fā)生了異常) using (StreamWriter file = new StreamWriter("test.txt")) {file.Write("test"); }
yieldC#語言中允許使用yield關(guān)鍵字來表示迭代器。在Java中,迭代器只能用類(可以是匿名的)來定義,且需要很多的樣板代碼。下面是一個能夠讀取可迭代的輸入(可以是數(shù)組)并且返回所有偶數(shù)成員的迭代器的例子。 public static IEnumerable<int> GetEven(IEnumerable<int> numbers) {foreach (int i in numbers){if (i % 2 == 0)yield return i;} }

回調(diào)和事件處理[編輯]

數(shù)值應(yīng)用[編輯]

多種語言特色的存在是為了充分的支持應(yīng)用程序在數(shù)學(xué)和金融領(lǐng)域計算。[1]在這一類中,Java提供關(guān)鍵字strictfp可以在代碼段中使浮點運算嚴(yán)格執(zhí)行。這可以保證運算在所有的平臺上都返回相同精確的結(jié)果。 與此不同C#為確保十進制小數(shù)浮點運算準(zhǔn)確,在?decimal?類型中內(nèi)嵌了這種機制。但在二進制小數(shù)浮點運算中舍棄了這種機制(float,?double)。 在二進制所有的類型中描述十進制數(shù)因為不精確會存在舍入誤差。所以在金融應(yīng)用方面十進制小數(shù)類型的精確顯得很重要。 Java中BigDecimal類也提供了這些特性。任意精度小數(shù)算法 (BigDecimal) 和任意精度整數(shù)算法 (BigInteger?) 的類為其提供任意精度的數(shù)值運算。 盡管有第三方實現(xiàn)了這些類,但是.NET框架(3.5)的現(xiàn)行版本當(dāng)前并沒有提供這些。(參見Arbitrary-precision arithmetic) Java不能為庫定義類型(高精度小數(shù)、復(fù)數(shù)等原始類型)提供一個統(tǒng)一標(biāo)準(zhǔn),為了達到這個目的,C#提供了如下內(nèi)容:

  • 能夠提供方便語法的運算符重載和索引(看下面)。
  • 隱性和顯性轉(zhuǎn)換;允許諸如嵌入式int 類型隱性轉(zhuǎn)換為long類型的存在。
  • 值類型和基于值類型的屬性;在Java中每個常規(guī)類型必須被存放在堆棧中,它對常規(guī)類型和存儲類型的性能是不利的。

除此之外,C#能用checked和unchecked運算符幫助數(shù)學(xué)計算,當(dāng)在一段代碼中出現(xiàn)算數(shù)溢出時它能夠檢測出是否能夠繼續(xù)運行。它也提供在內(nèi)嵌數(shù)組的某些應(yīng)用方面有優(yōu)勢的矩陣。[1]

運算符重載[編輯]

相比Java,C#包含了許多可數(shù)的便利。其中,例如運算符重載、用戶自定義類型,許多都被大批的C++程序員所熟悉。 它還具有“外在的成員實現(xiàn)”,這樣可以讓一個類明確的實現(xiàn)一個接口中的方法,與自己類中的方法分離。或者為分別來自兩個接口中,具有相同函數(shù)名和簽名的函數(shù)提供不同的實現(xiàn)。 C#包含了“索引器”,它可以當(dāng)作是一種特殊的運算符(像C++中的operator[]),或者是用?get/set?訪問器來訪問類屬性。一個索引器用this[]來標(biāo)明, 并且需要至少一個索引參數(shù),該參數(shù)可以為任意類別:

myList[4] = 5; string name = xmlNode.Attributes["name"]; orders = customerMap[theCustomer];

Java沒有提供運算符重載是為了阻止特征濫用,還有為了語言的簡單。[2]?C#允許運算符重載(以確定的幾個限制來確保邏輯上的一致為條件),如果小心地使用,可以使代碼更加簡潔和易讀。

?

方法[編輯]

在C#中,方法在默認(rèn)狀態(tài)下是非虛擬的,如果希望得到一個虛方法則必須明確地用 virtual 修飾符進行聲明,而在Java當(dāng)中,所有非靜態(tài)、非私有的方法都是虛方法。虛方法保證被調(diào)用的總是該方法最近被重寫的那個實現(xiàn)。但是,由于各個重載方法之間不能被正常地進行內(nèi)聯(lián),而使得在方法調(diào)用上需要花費一個相當(dāng)長的運行時間,并且需要通過虛方法列表進行間接的調(diào)用。然而,包括Sun公司所推薦的實現(xiàn)方法在內(nèi)的一些Java虛擬機的實現(xiàn)方法,則會對最普遍被調(diào)用的那些虛方法執(zhí)行內(nèi)聯(lián)。在java中,方法在默認(rèn)狀態(tài)下是虛擬的。(盡管他們能通過使用“final“修飾符來密封以使他不允許被覆蓋)。沒有什么辦法讓subclass或derived class以同樣的名字定義一個新的、無關(guān)聯(lián)的方法。 這就會產(chǎn)生一個問題,即當(dāng)一個基類由一個不同的人定義,這時就有可能出現(xiàn)一個與派生類中已經(jīng)定義過的一些方法有著相同的名字和標(biāo)簽的新的版本的方法定義。在Java中,這種情況將意味著派生類中的同名方法會隱式的重寫基類中的方法,盡管這種結(jié)果不是所有設(shè)計者的真正意圖。為了防止這種版本問題,C#中要求將派生類中需要重寫虛方法的部分進行顯示的聲明。 如果一個方法需要被重寫,那么必須指定override修飾符。如果不希望進行方法重寫,而且類的設(shè)計者僅僅希望引出一個新的方法以影射舊的方法,那么就必須含有new關(guān)鍵字。New關(guān)鍵字和override關(guān)鍵字也避免了由于基類中的protecte方法或public方法在它的某一個派生類中被使用時所帶來的問題。Java中重新編譯將導(dǎo)致編譯器把派生類中的這種方法當(dāng)做是基類方法的重寫,而這可能并不是基類的開發(fā)者想要的。

而C#編譯器將會把這種方法默認(rèn)為new關(guān)鍵字已經(jīng)被指定,但仍會對這種結(jié)果發(fā)出警告。為了部分地容納這些版本問題, Java 5.0中引入了@override注釋,但為了保護它的向后兼容這種做法不會被當(dāng)作是強制性的,所以它并不能阻止上述意外的重寫情況。然而對于C#中的override關(guān)鍵字,它能有助于確保基類中具有相同簽名的方法仍然存在,并且能被正確的重寫。

顯式接口實現(xiàn)[編輯]

如果在多個接口中有一個方法(或C #中的屬性)具有相同名稱和簽名,當(dāng)一個類在實現(xiàn)這些接口時這些重名的成員就會產(chǎn)生沖突。一個解決方法是通過為所有接口實現(xiàn)一個默認(rèn)共同的方法。如果必須要分開來實現(xiàn)(因為這個方法確實要實現(xiàn)某個特殊的目的,或者是因為各個接口的返回值不一樣)。C#顯示接口的實現(xiàn)將解決這一問題。在java中消除命名沖突的問題只能通過重構(gòu)或者是定義更多的接口來避免。C#的顯示接口實現(xiàn)還能隱藏底層基礎(chǔ)的類和接口,因此使得減少類和接口的復(fù)雜性。

開包[編輯]

當(dāng)一個函數(shù)作為一個參數(shù)來傳遞并為后面的程序調(diào)用,這時候會出現(xiàn)一個問題:當(dāng)這個方法調(diào)用了它自己作用域內(nèi)的變量時會怎樣呢?C#中有真正的開包功能,方法的引用會完全的獲得它自己作用域范圍內(nèi)的變量。Java中,匿名內(nèi)部類只能調(diào)用到作用域內(nèi)的常方法,想要調(diào)用和更新內(nèi)部類的話,就必須通過開發(fā)人員的手工聲明額外的間接的父類來實現(xiàn)。

Lambdas和表達樹[編輯]

C#中的一個特殊類型稱" lambdas"。 他們不是方法也不可能構(gòu)成類接口的部分; 他們只是在功能模塊中。 在lambda函數(shù)頂部可以定義的一個詳細(xì)結(jié)構(gòu)體稱為表達樹。 不管他們是被當(dāng)成執(zhí)行函數(shù)還是數(shù)據(jù)結(jié)構(gòu)都起決于編輯器類型,并且不管什么類型變量或參量都要賦值。 Lambdas和表示樹在LINQ中都是重要角色。 Java中沒有以lambdas或表達樹為特色的; 它的主要機制和方法定義是匿名內(nèi)部類句法。

部分方法[編輯]

與"部分類"相關(guān) C#允許部分方法在部分類之內(nèi)指定。 一個部分方法是方法的一個故意聲明并且在簽名上有一定的約束。 這些約束指定,如果任何類成員沒有被定義,那么可以安全地刪除。 這個特點允許代碼提供大量的監(jiān)聽點(像GoF設(shè)計模式中的"模板方法")而不用花費多余時間,如果另一個類成員在編譯時沒有引用它們。而 Java沒有對應(yīng)的概念。

?

擴展方法[編輯]

用一個特殊的this指定在一個方法的第一個參數(shù)C#允許這個方法扮演成第一個參數(shù)類型的一個成員函數(shù)。這個外來類的“擴展”是完全句法的。這個擴展方法需要變?yōu)殪o態(tài)的,而且定義在一個完全的靜態(tài)類中。它必須服從在外部靜態(tài)方法上的任何限定,因此它不能摧毀對象封裝。這個“擴展”僅僅是在靜態(tài)宿主類的命名空間被引進的范圍內(nèi)是活躍的。在java里面,相同的效果可以通過一個另一個類的一般方法得到,但語法將是一個函數(shù)調(diào)用,而不是方法調(diào)用類的C#語法擴展。

發(fā)生器方法[編輯]

發(fā)生器方法是一個C#方法 ,這個方法被聲明為返回IEnumerable,IEnumerator接口或者這些接口的一般版本,該方法可以用?yield語法實現(xiàn)。它是一個無限的表現(xiàn)形式, 編譯器生成的補遺集,可大大減少所需的代碼遍歷或生成序列;雖然代碼只是通過編譯器生成。這個特征過去也經(jīng)常被用作實現(xiàn)無窮大的序列,就像斐波那契數(shù)列。java是沒有相應(yīng)的概念。

條件編譯[編輯]

與Java不同,C#使用預(yù)編譯指令實現(xiàn)了條件編譯的功能。它還提供了條件屬性,使方法只有在定義了編譯常量的時候才被執(zhí)行。這樣一來,只有在定義了DEBUG常量時,Debug.Assert()方法才會執(zhí)行,斷言成為了framework的特色。從1.4版本開始,Java開始提供斷言,默認(rèn)情況下在運行時被關(guān)閉,但也可以在調(diào)用JVM時使用 "-enableassertions" 或者 "-ea" 打開。

名字空間和源文件[編輯]

C#的命名空間和C++類似,但不同于Java的包機制,C#命名空間不會以任何方式依賴于源文件的位置,這與Java不同,Java的常規(guī)結(jié)構(gòu)要求源文件的位置必須和包目錄結(jié)構(gòu)相符。 這兩種語言都允許引入類庫( 例:import java.util.* ,Java方式),在引入類庫后,使用類時就可以直接通過類名引用。不同名字空間或包中可以具有相同名字的類,這樣類在使用時可以通過全限定名來引用,或者通過不同的名字只引入必要的類。基于這個問題,Java允許引入單個類(例:import java.util.List)。C#允許在引入類庫時 使用語句: using Console = System.Console來為一個類庫定義一個新名,它同樣允許以using IntList = System.Collections.Generic.List<int>的形式,引入特殊類庫。

Java有允許使用某些或所有,具有較短名字的靜態(tài)方法/領(lǐng)域的靜態(tài)import句法在類中(例如,允許foo(bar)可以從另一個類中被靜態(tài)的引進).C#有靜態(tài)類句法(不與Java的靜態(tài)內(nèi)在類混淆),制約類只包含靜態(tài)方法。 C# 3.0介紹的引申方法允許用戶靜態(tài)地增加方法到類型(比如,允許foo.bar 的地方可以是研究foo的種類的一個引進的引申方法)。

Sun Microsystems?軟件公司的Java編譯器要求,源文件的文件名必須匹配在它里面的唯一的公開類,而C#允許在同一個文件的多公開類,并且投入制約。 C# 2.0和以后的版本允許類定義被分割成幾個文件,通過使用在原始代碼的關(guān)鍵字partial。

異常處理[編輯]

Java支持檢查異常(checked exception)。C#中只支持非檢查異常情況。檢查異常強制程序員要么在方法中聲明一個異常拋出,要么用try-catch來捕獲異常。檢查異常可以有助于良好的編程習(xí)慣,以確保所有的錯誤都得到處理。但是Anders Hejlsberg,C#語言首席設(shè)計師,和其他人爭辯說,他們都在一定程度上對Java進行了拓展但是它們沒有被證明是有價值的除了幾個程序中的小例子。有一個評論介紹在檢查異常時鼓勵程序員使用空的catch塊,安靜的吃掉異常而不是讓異常傳播到更高水平的常規(guī)的異常處理:catch (Exception e) {}.另一種對于檢查異常的評論說一個新方法的執(zhí)行可能會引起意想不到的檢查異常被拋出,這是一個合同突破性變化.這可能發(fā)生在一個方法實現(xiàn)一個接口或者當(dāng)一個方法的基本實現(xiàn)改變時,此接口僅聲明有限的異常。為這種意料之外的的異常被拋出,一些程序員簡單的聲明這種方法能拋出任何類型的異常(“拋出異常”),這使檢查異常的目的無法實現(xiàn)。不過在某些情況下,異常鏈(exception chaining)能用于代替,捕獲異常后再拋出一個異常異常.例如,如果一個對象訪問數(shù)據(jù)庫而不是文件時被改變,那么可以捕獲?SQLException異常并且作為IOException異常重新拋出. 因為調(diào)用者也許并不需要知道對象內(nèi)部的工作方式。

在處理try-finally的聲明時兩種語言也是有差別的。即使try塊包含像throw和return的control-passing語句,finally塊也總是要執(zhí)行。在Java中,這可能導(dǎo)致意外的行為,如果try塊最后有return語句返回一個值,然后執(zhí)行后的finally塊也會有return語句返回一個不同的值。 C#利用禁止任何像return或者break的control-passing語句來解決這一問題。 使用try-finally 塊的普遍原因是為了保護管理代碼的資源,所以珍貴的資源被保證在finally 塊中發(fā)布。作為句法速記為共同的設(shè)想的using語句在C#中處于顯著地位,其中using的對象的Dispose()方法總是被調(diào)用。

Finally塊和未捕捉的異常[編輯]

(C# 派生的異常特點)對CLI(公共語言基礎(chǔ))的ECMA(歐洲電腦廠商協(xié)會)標(biāo)準(zhǔn)指出在堆棧的兩次搜索中處理異常。ECMA-355 4th Edition 12.4.2.5 Overview of exception handling首次通過嘗試找到一個匹配的 catch 塊,如果沒有找到就終止該程序。只有當(dāng)找到匹配的 catch 塊時,才會在第二步執(zhí)行,從而運行干預(yù)的finally塊。這使得問題在程序狀態(tài)還沒第一次被finally塊修改前被診斷;它也消除了當(dāng)程序在未知狀態(tài)下,finally塊可能有副作用的風(fēng)險(例如,外部數(shù)據(jù)的損壞或進一步引發(fā)的異常)。

Java語言規(guī)范中指出finally塊中的代碼總會執(zhí)行即使異常沒有被捕獲,并且舉出實例代碼演示期待的結(jié)果。[3]

底層的代碼[編輯]

Java Native Interface?(JNI)的特征是允許Java代碼調(diào)用非Java代碼。然而,JNI要求被調(diào)用的代碼必須遵循Java提供的一些在類型和名稱上的約定。這種方法是為了適應(yīng)Java和其他代碼更好的交互。這些代碼必須是非Java代碼,常常是C或者C++代碼。JNA提供一種更加方便的Java代碼與其他代碼的交互,僅僅需要寫一些Java編寫的接口代碼,但是性能會付出一點代價。

另外,第三方類庫為JAVA-COM提供橋接,像JACOB?(自由軟件),J-Integra for COM?(專有軟件)

.NET平臺調(diào)用(P/Invoke)通過允許從C#調(diào)用微軟稱之為不受托管代碼提供同樣的的功能,通過元數(shù)據(jù)屬性程序員可以精確的控制如何調(diào)用參數(shù)和結(jié)果,因此可以避免額外編譯代碼的需要。平臺調(diào)用允許幾乎完全的對程序的API的訪問(像Win32或POSIX)但是限制對c++類庫的訪問。另外,.NET框架也提供一個.NET-COM網(wǎng)橋,允許對COM組件的的訪問就像是訪問本地的.NET組件。

C#中還允許程序員禁用正常類型檢查和CLR中其他的安全保證功能 ,這樣就使得指針變量的使用成為可能。當(dāng)此功能被使用時,程序員必須用unsafe關(guān)鍵字將相應(yīng)的代碼段進行標(biāo)記。JNI ,P/Invoke,和“unsafe”的代碼段是相當(dāng)冒險的部分,它揭露了可能的安全漏洞和應(yīng)用不穩(wěn)定。使用unsafe的一個優(yōu)勢是,通過P/Invoke或JNI運行于托管運行環(huán)境中的代碼是讓程序員在比較熟悉的C #環(huán)境中繼續(xù)工作以完成某些任務(wù),否則將需要調(diào)用非托管代碼。使用不安全代碼的程序或程序集必須通過進行特殊的轉(zhuǎn)換才能被編譯并且將依此被標(biāo)記。這使得運行時環(huán)境在潛在地執(zhí)行有危險的代碼前要采取特別的預(yù)防措施。

參考文獻[編輯]

  • ^?跳轉(zhuǎn)至:1.0?1.1?Java for Scientific Computation: Prospects and Problems?(PDF).[2009-05-01]. (原始內(nèi)容?(PDF)存檔于2007-09-22).
  • 跳轉(zhuǎn)^?August 1998 Java News
  • 跳轉(zhuǎn)^?Java Language Spec. 3rd Edition 14.20.2 Execution of try-catch-finally
  • 外部鏈接[編輯]

    • Contrasting C# and Java Syntax
    • Java vs. C# - Code for Code Comparison
    • Nine Language Performance Round-up
    • Java and C-Sharp Compared
    • MSDN:?The C# Programming Language for Java Developers
    • Standard ECMA-334 C# Language specification
    • Java Language Specification (Sun)
    • 31 Differences between C# and Java

    from:?https://zh.wikipedia.org/wiki/%E6%AF%94%E8%BC%83C%E2%99%AF%E5%92%8CJava

    總結(jié)

    以上是生活随笔為你收集整理的比较C#和Java的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。