2012-01-18 31 views
20

Number亞類包原始數值類型(ByteIntegerDoubleFloatLong,和Short)。爲什麼在java中是有一個包裝爲每個原語類型

他們服務的目的是什麼?

+9

基本上每一個答案都提到能夠將包裝類添加到默認集合是原因的一部分。然而,應該注意的是,當你有數百萬和數百萬個這樣的基元被打包和解包時,比如* HashMap *等,你可以通過使用第三方原始支持的集合來獲得巨大的內存和速度提升,例如* Trove *和它的* TIntLongHashMap *等。因此,將*(int,long)*條目放入* HashMap *是「方便的」,但它不是一種有效的操作方式。膨脹量實際上是驚人的。 – TacticalCoder 2012-01-18 19:40:58

+4

我會加入不是'Number'和'Void'的布爾值,它的概念上是'void'的封裝器。 – 2012-01-18 20:14:18

+0

還有'Character',它同樣不是'Number'(因爲它沒有擴展'Number')。 – 2014-11-25 20:17:21

回答

10

因爲包裝是Objects

  • Collections需求對象
  • 對象可以是instantiated爲null
  • 我們可以得到NullPointerException,而不是奇怪的行爲,如果你例如實例-1在原始
  • 的「包裝」有方便方法
0

把它們當作對象並把它們放入List,Maps et c

+0

爲了詳細解釋這個答案,Java泛型只適用於派生自Object類型的類型。因此,爲了使用諸如'ArrayList '這樣的類,基元需要具有對象類型包裝器。 – linuxuser27 2012-01-18 19:28:30

17

創建了這些包裝類,以便有一些方法可以將這些基本類型與各種容器類(如ArrayList)一起使用。由於原始類型不能直接強制轉換爲Object引用,因此它們存儲在包裝類中,以便在需要引用Object時使用它們。

+6

包裝類還封裝了對應於相應基元類型的有用行爲。假設你想將double的字符串表示轉換爲實際的double。 'Double.parseDouble(String)'就是這樣做的。另外,讓我創建一個示例...考慮一個名爲'salary'的'Employee'對象。通常,這將是'double'類型。假設員工剛剛被招募並添加到系統中,但薪水未被輸入。 double將假定默認值爲0.'null'的值可能比0更有意義:) – 2012-01-18 19:36:09

0

因此,我們可以將原始數據類型添加到集合中。要將元素添加到集合中,它們必須是objects。所以,引入了Wrapper類,它讓我們創建了primitive data types的對象。

例如:

Arraylist : add(Object o) 

TreeSet:  add(Object o) 
5

許多早期的面嚮對象語言(Smalltalk的等),有這使得它更容易界定是不可知的,他們身邊穿梭值的類型一般操作的所有價值的共同"top type"

類型理論中的頂部類型,通常縮寫爲頂部或由向下粘合符號(⊤)表示,它是通用類型 - 包含感興趣類型系統中所有可能對象的類型。

Java沒有這樣的頂級類型,但是Object是最接近它的了。將原始值映射到Object的實例可以使其有效地用作頂級類型。

核心語言設施java.lang.reflect使用Object作爲替身頂部類型 - 當你沉思調用你傳遞一個方法Object S和找回的Object

1

Java API中的包裝類基本上有兩個主要目的:

  • 要讓原語包含在爲對象保留,等作爲被添加到集合,或返回了一個方法與物體的活動返回值。
  • 爲基元提供各種效用函數。這些函數中的大多數都與各種轉換有關:將元素轉換爲字符串對象並將其轉換爲字符串對象,以及將基元和字符串對象轉換爲不同的基(或基),例如二進制,八進制和十六進制。
+1

好的答案。我還要補充一點,包裝類允許你使用null,而不是初始化爲0或-1(在某些情況下可能是有效的值)。 – 2012-01-18 19:41:50

2

按照該鏈接java tutorial的原因是:

有三個原因,你可以使用一個號碼對象,而不是原始的:

  • 作爲期望一個方法的參數一個對象(通常用於處理數字集合)。
  • 使用由類定義的常量,例如MIN_VALUE和MAX_VALUE,它們提供數據類型的上限和下限。
  • 使用類方法將值轉換爲其他基本類型以及從其他基本類型轉換值,轉換爲字符串和從字符串轉換以及在數字系統(十進制,八進制,十六進制,二進制)之間進行轉換。
0

就個人而言,我用它們作爲方法的參數,所以我不必擔心被傳遞數的類型,然後我可以用這樣的doubleValue()方法來獲取價值並能繼續不用擔心傳入的內容。

這是獲得抽象基類的基本原因。

2

Java設計人員 - 出於好的原因或者不好 - 不選擇Object的所有類型。 原始類型如int,long,char等並不基於Object,並且因爲它們具有相當不同的語義,就像它們通過值傳遞而不是通過引用傳遞一樣。

Integer/Long基本上只是包裝類,使基本類型的行爲像任何其他類型,以便能夠在類或對象更適合的上下文中使用它們。

例如,由於語義的差異,集合必須有兩個版本,一個用於Object,另一個用於基本類型。更簡單的做一個單一版本的集合,然後包裝原始類型。

+0

我認爲他們選擇引用類型/原始類型區別的主要原因是它們可以避免在本地變量中使用的基元的堆分配。他們本可以採用更豐富的[無私/自私](http://erights.org/elib/equality/same-object.html)價值區分,但這會使語言複雜化。 – 2012-03-09 18:39:05

+0

@MikeSamuel:我沒有聽說過用這種術語描述的東西,但我認爲有一種通用類型的對象引用會造成語義上的弱語言,因爲類型爲「list 」的字段可能取決於環境封裝了被引用的對象,它現在的可變狀態,兩者或兩者都不(只是封裝狀態永遠不會改變)。如果不是由於語言學上的失敗而無法確定一個對象的哪些方面被封裝在一個領域中,像對象克隆和對象平等這樣的東西可以以聲明方式而不是命令性的方式處理。 – supercat 2012-09-11 21:56:30

+0

@supercat,我不確定我關注。 Scala設法在Java的對象模型之上爲代數數據類型建立了豐富的等價性,所以在我看來,在Java中缺乏聲明性的比較/拷貝操作符是一個優先事項,而不是由於類型系統中的缺陷。 – 2012-09-11 22:04:50

0

有一種特定類型的「指針」可以指向任何類型(如C/C++中的void)。我想指的是java.lang.Object

例如你可以這樣做:

List<String> aList = new ArrayList<String>(); 
Object o = aList; 

這不適用於原語,即有原語沒有void引用類型。即原始類型無法引用任何類型的基元類型。

所以,如果你想有一個算法在任意變量上運行,你可以使用java.lang.Object類型的變量。
如果任意值是基元,請使用適當的對象包裝來包裝它們並使用java.lang.Object引用來操作它們。

您可以在Collections看到這個問題,以及

0

包裝類原始數據類型的對象代表,以便每當有使用他們,因爲我們必須要使用它們對象的情況。 當需要效率時我們需要對象和原語的包裝器用法。

0

1st - 爲了使java完全面向對象。我們不能通過對方法的引用傳遞一個原始類型,並且許多Java實現的標準數據結構對對象進行操作:例如(ArrayList,HashSet,HashMap等),所以他們需要這些對象參考文獻

相關問題