C#与Java的比较(转)
生活随笔
收集整理的這篇文章主要介紹了
C#与Java的比较(转)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
出處:http://www.cnblogs.com/zhucai/archive/2011/02/16/csharp-compare-java.html
這篇文章對C#與Java做一個(gè)語言級的對比,方便C#轉(zhuǎn)Java或Java轉(zhuǎn)C#的人有個(gè)大致了解。
這里大致用C#3.0與Java6.0做比較。
寫完后得知維基百科里有更加全面得多的比較:
?
?
| ? | ||
| 基本類型 | ? | 基本類型 |
| C#中有無符號數(shù),Java沒有。 C#中有值類型,且可自己定義值類型的結(jié)構(gòu)體(struct)。 Java中的基本類型(或叫基元類型)即為值類型,但Java沒有結(jié)構(gòu)體,所以不能自定義值類型。 C#中的值類型(包括所有基本類型)間接繼承自O(shè)bject,有自己的方法可以調(diào)用;Java中的值類型(即基本類型)不繼承自O(shè)bject,只是簡單的數(shù)據(jù),沒有方法可以調(diào)用。 C#中int等同于System.Int32,是值類型;bool等同于System.Boolean;等。 Java中int是基本類型,是值類型,而Integer是引用類型,Integer是int的包裝器,int自身沒有方法,Integer有一些方法;int與Integer之間可隱式轉(zhuǎn)換(導(dǎo)致裝箱和拆箱),但當(dāng)Integer值為null的時(shí)候會在運(yùn)行時(shí)拋出異常。boolean等類似。 Java中的int與Integer的對應(yīng)在C#中類似int和Nullable<int>的對應(yīng),它們的后者都是前者的包裝,且后者可以等于null。但Nullable<int>實(shí)際上仍然是值類型的(所以仍然很輕量級),所以從內(nèi)存上講C#中int和Object的對應(yīng)更接近Java的對應(yīng)一些。C#中Nullable<int>到int的轉(zhuǎn)換必須顯式進(jìn)行,因?yàn)镹ullable<int>中的值為null時(shí)會引發(fā)運(yùn)行時(shí)異常。 其他基本類型與之類似。 | ||
| ? | ||
| 委托,事件 | ? | [無] |
| C#中的委托可以認(rèn)為是方法的類型化,于是可以將方法放在變量里傳遞。事件是對委托做了一層包裝。 Java通過接口來實(shí)現(xiàn)C#中委托和事件的功能,可通過匿名類來達(dá)到C#中匿名委托的作用(同樣也能實(shí)現(xiàn)閉包的功能)。 另,C#中也有匿名類,但C#和Java的匿名類剛好各做各的事情:Java中的匿名類只有方法沒有數(shù)據(jù);C#中的匿名類只有數(shù)據(jù)沒有方法。 | ||
| ? | ||
| 非托管 | ? | [無] |
| C#可以有非托管代碼,可以有指針等。Java沒有。 | ||
| ? | ||
| 索引器 | ? | [無] |
| C#有索引器,可方便容器類實(shí)現(xiàn)類似數(shù)組的效果。Java沒有,Java的容器基本上用put,get,set等方法達(dá)到同樣效果。 | ||
| ? | ||
| 屬性 | ? | [無] |
| C#的屬性通過在內(nèi)部定義get/set方法,使外部使用時(shí)像是在使用變量字段,但其實(shí)是在調(diào)用get/set方法,以達(dá)到透明的封裝數(shù)據(jù)的目的。 Java沒有屬性的概念。Java通過約定為字段XX添加getXX,setXX方法達(dá)到同樣的目的。 | ||
| ? | ||
| 預(yù)編譯指令 | ? | [無] |
| C#有預(yù)編譯指令可方便調(diào)試,且有ConditionalAttribute來描述方法。Java沒有。 | ||
| ? | ||
| 操作符重載 | ? | [無] |
| C#可重載操作符。Java沒有。 Java自己重載了String的+和+=,但沒有重載==,這是我這段時(shí)間犯的最多的錯(cuò)誤。C#中String的==是比較值相等,Java中==是Object的默認(rèn)行為:比較引用相等,要比較值相等得用equals方法。(這么多年編程以來,我似乎從來沒有遇到過要比較兩個(gè)字符串變量的引用相等。對于比較值相等來講,==符號比equals方法調(diào)用看上去優(yōu)雅得多,況且方法調(diào)用還得注意空指針的情況) | ||
| ? | ||
| 內(nèi)部類 | ? | 內(nèi)部類 |
| Java的內(nèi)部類可以直接訪問外部類的實(shí)例成員。 C#的不行。C#的內(nèi)部類等同于Java的靜態(tài)內(nèi)部類。 | ||
| ? | ||
| goto、switch | ? | [goto]、switch |
| C#允許用goto。Java的goto是保留關(guān)鍵字,不能使用。但Java允許有標(biāo)簽,在有嵌套循環(huán)時(shí)可以在continue、break后面跟標(biāo)簽名。 C#的switch可以使用long、String;Java不可以。 Java的switch中的case子句在后面沒有跟break的情況下直接跳到下一個(gè)case子句; C#中只有在前一個(gè)case沒有任何代碼的情況下才允許不寫break直接跳到下一個(gè)case,C#中可以通過goto跳轉(zhuǎn)到另一case。 | ||
| ? | ||
| enum | ? | enum |
| C#中的枚舉是值類型,且其基于數(shù)值類型(默認(rèn)基于int),可設(shè)置枚舉項(xiàng)對應(yīng)的數(shù)字,不能在其中添加方法等任何其他成員。 Java中的枚舉是引用類型(Java除了基本類型外,任何類型都是引用類型),不是基于數(shù)值類型。除了不能繼承外,它跟普通類差別不大,可以添加成員方法和成員變量等(當(dāng)然也就可以重寫toString方法)。 C#和Java的枚舉都可以用于switch。 可以將C#的枚舉作為數(shù)值看待而直接進(jìn)行位運(yùn)算,因此可以在一個(gè)變量中存儲多個(gè)位標(biāo)記。 Java的枚舉跟數(shù)值沒有直接關(guān)系,因此不能直接這么用。Java用EnumSet來存儲枚舉標(biāo)志,不需要直接使用位運(yùn)算,更遠(yuǎn)離底層。 | ||
| ? | ||
| override | ? | @Override |
| C#能被重寫的方法必須添加virtual關(guān)鍵字聲明為虛方法,派生類重寫子類方法時(shí)添加override關(guān)鍵字。 Java默認(rèn)方法都可被重寫,派生類和子類方法簽名一樣時(shí)被認(rèn)為是重寫。要聲明不能被重寫的方法需在方法前加final關(guān)鍵字。重寫時(shí)可以在方法前添加標(biāo)注(即C#中的定制特性)@Override,這樣一旦此方法找不到被重寫的方法時(shí)編譯器會報(bào)錯(cuò),以防止拼寫錯(cuò)誤。 | ||
| ? | ||
| 定制特性 | ? | 標(biāo)注 |
| C#用中括號[]將定制特性括起來。Java用@打頭,后面跟定制特性的名字。 | ||
| ? | ||
| 泛型 | ? | 泛型 |
| Java中泛型實(shí)現(xiàn)使用的擦除機(jī)制,為類型參數(shù)傳入類型并不導(dǎo)致新類型出現(xiàn),即傳入了類型參數(shù)后在運(yùn)行時(shí)仍然完全不知道類型參數(shù)的具體類型,它的目的是為了兼容非泛型(所以可以在泛型和非泛型之間隱式轉(zhuǎn)換,會有編譯警告但不會有編譯錯(cuò)誤,這當(dāng)然其實(shí)并不安全);這同時(shí)衍生了一系列問題:不能定義泛型類型參數(shù)的數(shù)組如T[],不能通過new T()的方式實(shí)例化泛型,等。 Java的泛型不支持值類型(使用的話會被自動包裝成引用類型)。 | ||
C#的泛型在類型參數(shù)傳入類型后會產(chǎn)生一個(gè)新類型(雖然CLR的優(yōu)化機(jī)制會使引用類型共享同樣的代碼),可以在運(yùn)行時(shí)得到類型參數(shù)的類型信息。可以定義泛型數(shù)組,可以添加約束使其可以new。C#的泛型可以使用值類型(不會被裝箱)。 對于Java的泛型,簡單的講,它的好處只在編譯時(shí),運(yùn)行時(shí)沒有任何泛型的意義。當(dāng)你在使用已有的泛型類時(shí),這通常能滿足要求;但如果你要自己定義泛型類,那你得知道它有多少你覺得它應(yīng)該可以但事實(shí)上不可以的事情。 |
| ? | ||
| ? | ||
| 參數(shù)引用傳遞 | ? | [無] |
| C#允許使用關(guān)鍵字out,ref顯式指定參數(shù)傳遞方式為引用傳遞。 Java只有值傳遞。 | ||
| ? | ||
| @字符串 | ? | [無] |
| C#在寫字符串時(shí)可以在引號前加個(gè)@符號來取消/的轉(zhuǎn)義作用。 Java沒有。 | ||
| ? | ||
| ?? | ? | [無] |
| C#的??二元操作符當(dāng)前面的表達(dá)式不為null時(shí)返回前面表達(dá)式的值,前面表達(dá)式為null時(shí)返回后面表達(dá)式的值。 Java沒有。 | ||
| ? | ||
| using | ? | import |
| C#可以用using為命名空間或類指定別名。(using還有Dispose的使用方式,與命名空間無關(guān)) Java的import可以引入類或包(即C#的命名空間),static import可以引入類的成員。 | ||
| ? | ||
| 初始化 | ? | 初始化 |
| C#調(diào)用基類構(gòu)造函數(shù)的語法為: SubClass() : base() { } Java調(diào)用基類構(gòu)造函數(shù)的語法為: SubClass(){ ?? super(); } C#和Java都可以用類似的語法調(diào)用同一個(gè)類的其他構(gòu)造函數(shù)。(分別將base和super換成this) Java有代碼塊概念,會在構(gòu)造函數(shù)之前執(zhí)行(基類的構(gòu)造函數(shù)之后)。 在成員變量聲明時(shí)賦值,Java允許其賦值表達(dá)式中引用前面聲明的另一個(gè)變量,如: private int x = 1; private int y = x + 10; 這里變量y的賦值語句有變量x。 C#不允許這樣做。 | ||
| ? | ||
| interface | ? | interface |
| Java的接口內(nèi)允許有內(nèi)部類、靜態(tài)字段等。 C#不允許。 | ||
| ? | ||
| readonly,const | ? | final |
| C#的const是絕對的常量,必須在聲明語句中同時(shí)賦值,只有數(shù)值、枚舉和String可以聲明為const。const的值會內(nèi)聯(lián)到各個(gè)使用的地方。 C#的readonly表示變量在構(gòu)造函數(shù)執(zhí)行完之后是不能再變化的。它只約束變量本身,而無法約束變量引用(如果它是引用類型或者有成員是引用類型)的對象。 Java中的final(在約束變量的時(shí)候)看上去更像readonly。 但C#的readonly和const有個(gè)區(qū)別,readonly的int是不能作為switch的case語句的,const的可以。 而Java的final則是:有時(shí)候可以有時(shí)候不可以----編譯時(shí)可以得到明確值的可以,反之不可以。如: final int x = 1;?? // 這個(gè)可以 final int y = new Random().nextInt();?? // 這個(gè)不可以 那么可以理解為:編譯時(shí)能得到明確值的時(shí)候,final等同于C#的const(不清楚Java在這個(gè)情況下是否會內(nèi)聯(lián),估計(jì)不會);編譯時(shí)無法得到明確值的時(shí)候,final等同于C#的readonly。 | ||
| ? | ||
| [無] | ? | throws |
| Java在可能拋出異常時(shí),除了RuntimeException(包括派生類),都要么捕獲,要么在方法聲明中用throws關(guān)鍵字聲明出來表示繼續(xù)拋出。 C#沒有采用這種強(qiáng)制處理機(jī)制。 | ||
?
| ? | ||
| 功能相同但語法有差異的 | ||
| namespace == package (Java的package對文件結(jié)構(gòu)也有要求;C#沒有) internal == [默認(rèn)] (Java中不寫訪問修飾符即表示訪問權(quán)限是package;C#默認(rèn)是private。C#的internal protected在Java中沒有。) lock == synchronized (Java中synchronized可以修飾方法,C#可以用定制特性[MethodImplAttribute(MethodImplOptions.Synchronized)]達(dá)到同樣效果) ?: == extends,implements base == super is == instanceof (C#有as,Java沒有) typeof == .class [SerializableAttribute]定制特性 == Serializable接口 [NonSerializedAttribute]定制特性 == transient params == ... (可變數(shù)目參數(shù)) |
?
?
這個(gè)列表里,Java比C#更漂亮的地方基本上只有一處:枚舉。Java的枚舉更高層一些,更靈活。但內(nèi)存代價(jià)比C#的枚舉要高,這可能就是Android里仍然使用常量而不是枚舉的原因吧。
所以就從這次比較來講,C#幾乎完勝Java,而C#的新特性像完美的類型推斷、動態(tài)編程特性、Lambda表達(dá)式、LINQ等等這里都沒有列入比較。
當(dāng)然,.NET和Java兩大體系的比較,語言只是一個(gè)方面,還有平臺、IDE、開源等其他很多方面,這里就不說了。
轉(zhuǎn)載于:https://www.cnblogs.com/smileberry/archive/2012/08/30/2663269.html
總結(jié)
以上是生活随笔為你收集整理的C#与Java的比较(转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最短路径dijkstra
- 下一篇: [转]C#中的委托和事件(续)