標籤:top int操作 png val 對象 工作 center 建立 數組
首先說一下Java中的封裝類,Java語言是一個物件導向的語言,但是Java中的基礎資料型別 (Elementary Data Type)卻不是物件導向的,這在實際使用時存在很多的不便(比如,我們不能直接想集合Collections中放入原始類型值,因為集合只接收對象)。為瞭解決這個不足,在設計類的是為每個基礎資料型別 (Elementary Data Type)設計了一個對應的類進行代表,這樣八個和基礎資料型別 (Elementary Data Type)對應的類統稱為封裝類(Wrapper Class)。
基礎資料型別 (Elementary Data Type) |
封裝類 |
byte |
Byte |
boolean |
Boolean |
short |
Short |
char |
Character |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
自動裝箱就是Java自動將原始類型轉化為對應的對象,比如將int的變數轉化為Integer對象,這個過程叫做裝箱,反之將Integer對象轉化為int對象,這個過程叫做拆箱。又因為這個過程是自動發生的,所以又叫自動裝箱,自動拆箱。
ArrayList<Integer> arrayList = new ArrayList<Integer>();arrayList.add(1); //自動裝箱 int --> Integerint number = arrayList.get(0); //自動拆箱 Integer --> int
簡單點說,裝箱就是自動將基本類型轉化為封裝類型,拆箱就是自動將封裝類型轉化為基本類型。
在自動裝箱的過程中,系統為我們執行了
Integer total = Integer.valueOf(1);
自動拆箱的過程中,系統為我們執行了
int number = total.intValue();
弊端:
有些情況中,自動裝箱如果不注意的話會建立多餘的對象,影響程式的效能。
Integer sum = 0; for(int i=1000; i<5000; i++){ sum+=i;}
上述代碼中 sum+=i 可以看成 sum = sum +i,但是這個 + 操作符不適用與Integer對象,首先sum進行自動拆箱操作,進行數值的相加操作,最後發生自動裝箱操作轉化為Integer對象。
其內部的變化如下:
sum = sum.intValue() + i;Integer sum = new Integer(result);
由於我們聲明的sum為Integer類型,在上面的迴圈中會建立將近4000個無用的對象,在這樣龐大的迴圈中,會降低程式的效能並且加重了記憶體回收的工作量。因此在我們編程時,需要注意到這一點,正確的聲明變數類型,避免因為自動裝箱引起的效能問題。
在Integer類內部包含了一些和int操作有關的方法,下面介紹一些比較常用的方法:
a、parseInt方法
public static int parseInt(String s)
該方法的作用是將數字字串轉換為int數值。在以後的介面編程中,將字串轉換為對應的int數字是一種比較常見的操作。使用樣本如下:
String s = “123”;
int n = Integer.parseInt(s);
則int變數n的值是123,該方法實際上實現了字串和int之間的轉換,如果字串都包含的不是都是數字字元,則程式執行將出現異常。
另外一個parseInt方法:
public static int parseInt(String s, int radix)
則實現將字串按照參數radix指定的進位轉換為int,使用樣本如下:
//將字串”120”按照十進位轉換為int,則結果為120
int n = Integer.parseInt(“120”,10);
//將字串”12”按照十六進位轉換為int,則結果為18
int n = Integer.parseInt(“12”,16);
//將字串”ff”按照十六進位轉換為int,則結果為255
int n = Integer.parseInt(“ff”,16);
這樣可以實現更靈活的轉換。
b、toString方法
public static String toString(int i)
該方法的作用是將int類型轉換為對應的String類型。
使用範例程式碼如下:
int m = 1000;
String s = Integer.toString(m);
則字串s的值是”1000”。
另外一個toString方法則實現將int值轉換為特定進位的字串:
public static int parseInt(String s, int radix)
使用範例程式碼如下:
int m = 20;
String s = Integer.toString(m);
則字串s的值是”14”。
另外說一個前兩天遇到的問題
int i = Integer.valueOf("222"); System.out.println(i);
在用findbugs查到了這個問題,進行了多餘的拆箱和裝箱操作,原因是 Interger.valuesOf("")返回的是 Integer對象,然後再拆箱到 int類型。
看幾個例子
int i = 128; Integer i2 = 128; Integer i3 = new Integer(128); //Integer會自動拆箱為int,所以為true System.out.println(i == i2); //true System.out.println(i == i3); //true System.out.println("**************"); System.out.println(i2 == i3); //false Integer i5 = 127;//java在編譯的時候,被翻譯成-> Integer i5 = Integer.valueOf(127); Integer i6 = 127; System.out.println(i5 == i6);//true /*Integer i5 = 128; Integer i6 = 128; System.out.println(i5 == i6);//false*/ Integer ii5 = new Integer(127); System.out.println(i5 == ii5); //false Integer i7 = new Integer(127); Integer i8 = new Integer(123); System.out.println(i7 == i8); //false
總結一下就是如果 Integer 和int類型相比,那麼會將Integer類型拆箱為int類型的然後進行數值比較,如果是 Integer i = new Integer (127);這種會建立新的 Integer對象,所以實際對比的是兩個對象,基本會返回false(當然如果和int類型相比也是返回 數值比較結果)。如果 是 Integer i1 = 127,Integer i2 = 127,這種比較的話,如果小於128 會返回true,大於等於128 會返回false。
為什麼會出現這樣呢,上面說到 integer i = 127, 會執行裝箱操作,實際上 是執行了 Integer.valueOf(127),我們看一下 valueOf函數
public static Integer valueOf(int i) { return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];}
它會首先判斷i的大小:如果i小於-128或者大於等於128,就建立一個Integer對象,否則執行SMALL_VALUES[i + 128]。
private static final Integer[] SMALL_VALUES = new Integer[256];
它們的值在(-128,128]這個範圍內,它們會拿到SMALL_VALUES數組裡面的同一個對象SMALL_VALUES[228],它們引用到了同一個Integer對象。
Java中的拆箱和裝箱