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