淺談C# vs Java (1) (轉)
CLR vs JVM:namespace prefix = o ns = "urn:schemas--com::office" />
1.概念
Microsoft一直在宣稱CLR(公共語言執行環境)是所謂得虛擬機器而並非JVM虛擬
機的概念。這是由於CLR將支援一切遵循CTS(公共語言規則)的語言在其上執行並且互不干擾,從這個概念上說CLR相較JVM來說更像一個平臺。
2.編譯
將原始碼編譯成為.class,透過java命令來執行。例如:
java test.class
而則將原始碼編譯成為.exe檔案。但這個exe檔案不同於傳統的exe檔案,它是由一個清單和MSIL(Microsoft中間語言)程式碼組成。格式大致如下:
PE(-Portable executable)頭 --- exe檔案頭
清單 --- 檔案中所包含的型別和類
跳轉命令 --- 跳轉到MSIL直譯器
MSIL程式碼
從以上的結構可以看到,C#同Java一樣能夠輕鬆被反編譯,不同的是,Microsoft還提供了用於讀取編譯後MSIL的工具ildasm。
另外,雖然Microsoft對這種結構提出了種種的好處,但是如果把MSIL看成是Java編譯後的程式碼(即.class檔案中的程式碼),那麼C#的檔案結構更象是把Java的執行命令和.class檔案已exe檔案的方式封裝起來。如下表:
C#
Java
PE頭
-
清單
關於這點將在部署一節中論述
跳轉命令
java命令
MSIL程式碼
.class檔案
分析了C#編譯結果,就會發現C#並沒有因為編譯成了可檔案,就依附於window平臺。從理論上說,如果有一個版的MSIL直譯器(實際上它是CLR的一部分)和一個Linux版的C#的,那麼就可以將window下編寫的C#的程式碼在Linux下重新編譯,於是就實現了所謂“處處編譯,處處執行”。而在這工程中,保持程式碼編譯一致性的CTS(公共語言規則),難怪有自由組織曾提議使用Microsoft的CLR&CTS構架來統一當前自由軟體界的編譯環境。
3.執行
Java早期是一種解釋性語言,後來為了提高採用了JIT(just-in-time)技術,還有一些工具可以將Java生成特定的的二進位制程式碼。
而C#也必不可少的選用了MSIL和JIT的機制。根據不同的情況可分為3類:
a) 時程式碼生成(Install-time code generation):將當前程式碼完全編譯成特定的CPU的二進位制程式碼。之所以叫做安裝時程式碼生成,是因為這個編譯過程是在安裝時進行的。
b) JIT:與Java的JIT方式相似。
c) EconoJIT(經濟性JIT):與JIT不同的是,它透過丟棄已產生出的,編譯過的程式碼回收,比較適用於少量記憶體的手持裝置。
4.部署
Java採用的是將包路徑和目錄相對應的方法,生成一層一層的目錄。之後又推出使用jar檔案封裝的方式。
C#採用的是後設資料紀錄的方法。所謂後設資料就是上文C#編譯結果結構中提到的“清單”。C#透過後設資料紀錄型別和類的資訊,相較Java的目錄結構和jar檔案方式,封裝性提高
了不少。不過目錄結構有一個好處是顯而易見,就是當有部分程式碼需要修改的時候,只要重新編譯需要修改的程式碼,並覆蓋相應的類就可以了。
一切都是
C#和Java都宣稱自己的一切都是物件,但是真正實現這一說法的恐怕只有SmallTalk。
這主要是因為將基本資料型別描述成物件所造成的程式碼方面的降低是很難讓人接受的。於是C#和Java都提出了關於這一問題的解決方案。
Java保留了基本資料型別,併為每一種型別提供了一個對應的類,如int型對應Integer類, long型對應Long類。當需要用類來描述基本資料型別時,即可透過生成其對應的類,如下程式碼:
int n = 5;
Integer in = new Integer(n);
使用後,又可以將對應類的值賦給基本資料型別,如下程式碼:
Integer in = new Integer(5);
int n = in.intValue();
相對應的,C#也採用了為基本資料型別提供對應類的方式,但在使用上採用的是開箱(unboxing)和裝箱(boxing)操作。所謂裝箱就是將基本資料型別轉換為對應類。而開箱的作用剛好相反。
當試圖將基本資料型別以一種與System.基類介面相匹配的方式使用時,將自動將它裝箱,使之能夠像一般物件一樣被使用。如下程式碼:
int n = 42;
Int32 in = n;
開箱的程式碼如下:
int n = 42;
Int32 in = n;
//注意:開箱時必須進行顯示的型別轉換
int n2 = (int)Int32;
有以上的例子可以看出,在一切都是物件的問題上,C#和Java的解決方式是很相似,
只是C#封裝了更多的操作細節。但是是否有系統來做這些操作可以提高語言本身的效率呢?Microsoft的回答肯定是肯定的。
小結
以上對C#和Java在編譯執行以及物件的設定等問題上作了比較,從中發現,C#在設計上大量模仿Java,但在具體實現上C#封裝了更多的細節,相較Java來說應該更易於使用,這大概是Microsoft的風格吧。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1000227/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 淺談java之設計模式(1)Java設計模式
- 淺談C#泛型C#泛型
- 淺談1——用Eclipse除錯JAVA程式Eclipse除錯Java
- 淺談C#取消令牌CancellationTokenSourceC#
- 淺談C#更改令牌ChangeTokenC#
- 淺談 Java集合Java
- Go vs Java vs C# 語法對比GoJavaC#
- 淺談 Java執行緒狀態轉換及控制Java執行緒
- 淺談Java抽象類Java抽象
- 淺談java泛型Java泛型
- 淺談Java迭代器Java
- 淺談Java併發Java
- 淺談微服務轉型微服務
- 淺談C#字串構建利器StringBuilderC#字串UI
- 淺談C#可變引數paramsC#
- 淺談 C# Assembly 與 IL (一):C# Assembly 與 ReflectionC#
- Database | 淺談Query Optimization (1)Database
- 淺談Java中的HashmapJavaHashMap
- 淺談Java序列化Java
- Java API 操作Docker淺談JavaAPIDocker
- 淺談java中的反射Java反射
- 淺談java內部類Java
- 淺談Java的反射原理Java反射
- 淺談Java記憶體模型Java記憶體模型
- 淺談Java —— Reflection機制(一)Java
- 淺談 Java多執行緒Java執行緒
- Java基礎之淺談介面Java
- Java基礎之淺談集合Java
- 轉載分享:淺談引導盤
- 淺談JavaScript的型別轉換JavaScript型別
- 淺談java中的併發控制Java
- 淺談Java中的內部類Java
- 淺談對java-GC的理解JavaGC
- Java基礎之淺談泛型Java泛型
- 淺談Java中的淺拷貝和深拷貝Java
- 淺談C#中重寫和隱藏的區別C#
- 淺談測試生涯如何轉型升級
- 淺談Java的反射機制和作用Java反射
- 淺淺談ReduxRedux