《Java 核心技术卷1 第10版》学习笔记------ 对象包装器、自动装箱、拆箱
? ? 有時, 需要將 int 這樣的基本類型轉(zhuǎn)換為對象。 所有的基本類型都冇一個與之對應(yīng)的類。例如,Integer 類對應(yīng)基本類型 int。通常, 這些類稱為包裝器 ( wrapper ) 這些對象包裝器類擁有很明顯的名字:Integer、Long、Float、Double、Short、Byte、Character 、Void 和 Boolean (前6 個類派生于公共的超類 Number)。對象包裝器類是不可變的,即一旦構(gòu)造了包裝器,就不允許更改包裝在其中的值。同時, 對象包裝器類還是 final , 因此不能定義它們的子類。
? ? 假設(shè)想定義一個整型數(shù)組列表。而尖括號中的類型參數(shù)不允許是基本類型,也就是說,不允許寫成 ArrayList<int>。這里就用到了 Integer 對象包裝器類。我們可以聲明一個 Integer對象的數(shù)組列表。
警告: 由于每個值分別包裝在對象中, 所以 ArrayList<lnteger> 的效率遠(yuǎn)遠(yuǎn)低于 int[ ] 數(shù)組。 因此, 應(yīng)該用它構(gòu)造小型集合,其原因是此時程序員操作的方便性要比執(zhí)行效率更加重要。
? ? 幸運的是, 有一個很有用的特性, 從而更加便于添加 int 類型的元素到 ArrayLisKlntegeP中。下面這個調(diào)用
list.add(3);將自動地變換成
list.add (Integer.value0f(3));這種變換被稱為自動裝箱(autoboxing。)
相反地, 當(dāng)將一個 Integer 對象賦給一個 int 值時, 將會自動地拆箱。也就是說, 編譯器將下列語句:
nt n = list.get(i); // 翻譯成 int n = list.get(i).intValue();甚至在算術(shù)表達(dá)式中也能夠自動地裝箱和拆箱。例如,可以將自增操作符應(yīng)用于一個包裝器引用:
Integer n = 3; n++;編譯器將自動地插人一條對象拆箱的指令, 然后進(jìn)行自增計算, 最后再將結(jié)果裝箱。
? ? 大多數(shù)情況下,容易有一種假象, 即基本類型與它們的對象包裝器是一樣的,只是它們的相等性不同。大家知道, == 運算符也可以應(yīng)用于對象包裝器對象, 只不過檢測的是對象是否指向同一個存儲區(qū)域, 因此,下面的比較通常不會成立。
Integer a = 1000; Integer b = 1000; if (a = b) . . .然而,Java 實現(xiàn)卻有可能( may) 讓它成立。如果將經(jīng)常出現(xiàn)的值包裝到同一個對象中,這種比較就有可能成立。這種不確定的結(jié)果并不是我們所希望的。解決這個問題的辦法是在兩個包裝器對象比較時調(diào)用 equals 方法。
注釋: 自動裝箱規(guī)范要求 boolean、byte、char 127, 介于 -128 ~ 127 之間的 short 和 int 被包裝到固定的對象中。例如,如果在前面的例子中將 a 和 b 初始化為 100,對它們進(jìn)行比較的結(jié)果一定成立。
關(guān)于自動裝箱還有幾點需要說明。首先, 由于包裝器類引用可以為 null, 所以自動裝箱有可能會拋出一個 NullPointerException 異常:
Integer n = null; System.out.printing * n); // Throws NullPointerException另外, 如果在一個條件表達(dá)式中混合使用 Integer 和 Double 類型, Integer 值就會拆箱,提升為 double, 再裝箱為 Double:
Integer n = 1; Double x = 2.0; System.out.println(true ? n : x); // Prints 1.0最后強調(diào)一下,裝箱和拆箱是編譯器認(rèn)可的,而不是虛擬機。編譯器在生成類的字節(jié)碼時, 插人必要的方法調(diào)用。虛擬機只是執(zhí)行這些字節(jié)碼。
使用數(shù)值對象包裝器還有另外一個好處。Java 設(shè)計者發(fā)現(xiàn),可以將某些基本方法放置在包裝器中, 例如, 將一個數(shù)字字符串轉(zhuǎn)換成數(shù)值。
要想將字符串轉(zhuǎn)換成整型, 可以使用下面這條語句:
int x = Integer.parselnt(s)這里與 Integer 對象沒有任何關(guān)系, parselnt 是一個靜態(tài)方法。但 Integer 類是放置這個方法的一個好地方。
警告: 有些人認(rèn)為包裝器類可以用來實現(xiàn)修改數(shù)值參數(shù)的方法, 然而這是錯誤的。由于 Java 方法都是值傳遞, 所以不可能編寫一個下面這樣的能夠增加整型參數(shù)值的 Java 方法。
public static void triple(int x) // won't work {x = 3 * x; // modifies local variable }將 int 替換成 Integer 又會怎樣呢?
public static void triple(Integer x) // won't work {x = 3 * x; // modifies local variable }問題是 Integer 對象是不可變的: 包含在包裝器中的內(nèi)容不會改變: 不能使用這些包裝器類創(chuàng)建修改數(shù)值參數(shù)的方法。
如果想編寫一個修改數(shù)值參數(shù)值的方法, 就需要使用在 org.omg.CORBA 包中定義的持有者( holder) 類型, 包括 IntHolder、BooleanHolder 等。每個持有者類型都包含一個公有 (!)域值,通過它可以訪問存儲在其中的值。
?
本文方法總結(jié):
java.lang.Integer 1.0
// java.lang.Integer 1.0int intValue( ) // 以 int 的形式返回 Integer 對象的值(在 Number 類中覆蓋了 intValue方法)。static String toString(int i ) // 以一個新 String 對象的形式返回給定數(shù)值 i 的十進(jìn)制表示。static String toString(int i ,int radix ) // 返回數(shù)值 i 的基于給定 radix 參數(shù)進(jìn)制的表示。static int parselnt(String s) static int parseInt(String s,int radix) // 返回字符串 s 表示的整型數(shù)值, 給定字符串表示的是十進(jìn)制的整數(shù)(第一種方法,)或者是 radix 參數(shù)進(jìn)制的整數(shù)(第二種方法 )。static Integer valueOf(String s) Static Integer valueOf(String s, int radix) // 返回用 s 表示的整型數(shù)值進(jìn)行初始化后的一個新 Integer 對象, 給定字符串表示的是十進(jìn)制的整數(shù)(第一種方法,) 或者是 radix 參數(shù)進(jìn)制的整數(shù)(第二種方法)。java.text.NumberFormat 1.1
Number parse(String s) // 返回數(shù)字值,假設(shè)給定的 String 表示了一個數(shù)值?
總結(jié)
以上是生活随笔為你收集整理的《Java 核心技术卷1 第10版》学习笔记------ 对象包装器、自动装箱、拆箱的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Java 核心技术卷1 第10版》学习
- 下一篇: 《Java 核心技术卷1 第10版》学习