2010-11-20 129 views

回答

28

C#有一個統一的類型系統。 所有C#類型,包括原始類型,例如從單個根object型 int和double,繼承。與類對象不同,這些基本類型是值類型。它們不是分開堆放,而是按價值傳遞。

當C#值類型(例如,基元int或用戶定義的結構)被放置在一個參數集合,它被存儲在與沒有指針一個密集陣列。這是可能的,因爲C#爲每個需要的不同參數「大小」定製參數化實例。這意味着當您實例化C#List<int>時,底層數組列表存儲密集打包的int數組。

來源:http://www.pin5i.com/showtopic-24376.html

的Java有幾個原始類型(INT,長雙,字節,等等) - 但是,他們是特殊的,因爲它們是不是面向對象的,他們不能用語言本身來定義。它們是值類型,不是分配堆,而是按值傳遞。

來源:Comparison of C# and Java - Unified type system(維基百科)

與此同時,Java還具有面向對象的原始的 「包裝」 類型(整數,長,雙,字節等),通常被稱爲boxed類型。這些是通過引用傳遞的堆分配對象,並且與上述基本類型並行存在。

在較新版本的Java,基本類型自動裝箱爲目標類型時必要的。這減輕了管理它們的大部分負擔,但它也可能導致微小的錯誤(另請參閱auto-boxing)。

相比於C#,Java中,內置的JDK集合框架總是設法對象指針的集合。爲了使它們以向後兼容的方式參數化,Java執行了一種稱爲type-erasure的技術,其中(在運行時)所有內容均被視爲容器內的對象(參數化類型檢查在編譯時執行)。

這意味着,你不能讓一個Java List<int>,您只能List<Integer>。而且,上面的列表實際上存儲了一個指向盒裝Integer對象的指針數組,它的大小是C#版本的兩倍,性能也大大降低。對於大多數使用情況,這種尺寸和性能的差異是無關緊要的。

在使用情況下,尺寸和性能是相關的,有兩種方法可供選擇:

  1. 當你知道你的名單提前大小,使用原生類型的數組,例如int[]。原生類型的數組打包在內存中,因此它們消耗的LOT更少,性能更高。
  2. 當你不知道你的名單提前大小,使用該包裝的原生陣列,從而能夠創建之後元素添加到它的一些第三方列表實現(一些例子:TroveColtFastutilGuava) 。
+0

我讀過一次大學項目,一個編程語言使用統一類型系統,既有基本類型和對象,但基本類型有一個隱藏的繼承,基本對象和基本類型,其中的子類一個隱藏的根類型 – umlcat 2011-04-01 17:45:40

+0

哈哈,聽起來很熟悉,這個項目發生了什麼umlcat lol – brumScouse 2012-05-04 11:52:12

+0

@brumScouse:不知道。我失去了鏈接。我開始在自定義寵物項目中應用我學到的知識。 Java和C#都不僅是對象編程。我認爲它可以擁有原始類型和一個統一的類型系統,它獨立於對象定向。 – umlcat 2012-12-31 17:37:06

12

這實際上不是C#的真實情況,並非所有類型都來自對象,就像99.9%的對象一樣。有一些非常奇怪的類型不能轉化爲對象。 唯一正式支持的是指針。 還有3個像TypedReference,RuntimeArgumentHandle這樣的不受支持的類,另外還有一個名字讓我感到失望。這三種類型與C++/C中的變長方法交互使用。我不會擔心他們太多。

+0

這是神經破壞探索這個神話的細節[這裏](https://blogs.msdn.microsoft.com/ericlippert/2009/08/06/not-everything-derives-from-object/)你能找出第三種不支持的類型?順便說一句,即使指針不支持,直到你將它們轉換爲「System.IntPtr」或「System.UIntPtr」值類型。 – RBT 2016-12-26 05:51:29