.NET(C#) | Java | |
---|---|---|
基本類型 | 基本類型 | |
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#中的匿名類只有數據沒有方法。 |
非託管 | [無] |
|
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;編譯時沒法獲得明確值的時候,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 == ... (可變數目參數) |