Java自動裝箱拆箱淺析

自動裝箱拆箱概念

在Java SE 5以後,爲基本數據類型提供了自動裝箱和拆箱功能,使得將基本類型轉換與對象之間的轉換變得極其便捷。
| 基本數據類型    | 包裝類    |
| int(4字節)     | Integer   |
| byte(1字節)    | Byte      |
| short(2字節)   | Short     |
| long(8字節)    | Long      |
| float(4字節)   | Float     |
| double (8字節) | Double    |
| char(2字節)    | Character |
| boolean(未定)  | Boolean   |

Integer i = 100;(拆箱)
int j = i;(裝箱)

自動裝箱拆箱的實現

Integer i = 100;(拆箱)
int j = i;(裝箱)
//上面兩行代碼的反編譯以下:
Integer i = Integer.valueOf(100);//拆箱
int j = i.intValue();//裝箱
對於其餘基本類型的裝箱和拆箱和int相似。

案例分析

Integer

(1)案例
int a = 100;
int b = 100;
System.out.println(a == b);
int c = 200;
int d = 200;
System.out.println(c == d);
Integer e = new Integer(100);
System.out.println(a == e);
//結果
true
true
true
//反編譯
byte a = 100;
byte b = 100;
System.out.println(a == b);
short c = 200;
short d = 200;
System.out.println(c == d);
Integer e = new Integer(100);
System.out.println(a == e.intValue());

若是改成下面的代碼呢?
(2)案例
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
//int c = 200;
Integer c = 200;
Integer d = 200;
System.out.println(c == d);//輸出true
Integer e = new Integer(100);
System.out.println(a == e);
//結果
true
false
false
//反編譯結果
Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b);
Integer c = Integer.valueOf(200);
Integer d = Integer.valueOf(200);
System.out.println(c == d);
Integer e = new Integer(100);
System.out.println(a == e);

(1)案例和(2)案例爲啥不同呢?java

        當 "=="運算符的兩個操做數都是包裝器類型的引用,則比較的是對象;而若是其中有一個操做數是表達式(即包含算術運算)或是基本類型則比較的是數值。spa

緣由分析:咱們查看一下valueOf()源碼code

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        //這裏有個IntegerCache
        return IntegerCache.cache[i + (-IntegerCache.low)];
        //當大於high小於low時才新建
    return new Integer(i);
}
//能夠得知low=-128,high=127
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

Boolean

boolean a = true;
boolean b = true;
System.out.println(a == b);

Boolean c = true;
Boolean d = true;
System.out.println(c == d);
//結果
true
true
//反編譯
boolean a = true;
boolean b = true;
System.out.println(a == b);
Boolean c = Boolean.valueOf(true);
Boolean d = Boolean.valueOf(true);
System.out.println(c == d);

爲何是true?咱們查看valueOf()源碼orm

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}
//注意TRUE和FALSE爲常量
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

Double

double a = 1.0;
double b = 1.0;
System.out.println(a == b);
Double c = 1.0;
Double d = 1.0;
System.out.println(c == d);
//結果
true
false
//反編譯
double a = 1.0D;
double b = 1.0D;
System.out.println(a == b);
Double c = Double.valueOf(1.0D);
Double d = Double.valueOf(1.0D);
System.out.println(c == d);
//valueOf()源碼
public static Double valueOf(double d) {//建立了新對象
    return new Double(d);
}

Long

Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d);//-127~128
System.out.println(e==f);//>128
System.out.println(c==(a+b));//自動拆箱
System.out.println(c.equals(a+b));//都是Integer類型
System.out.println(g==(a+b));//自動拆箱,向上轉型爲long
System.out.println(g.equals(a+b));//類型不匹配
System.out.println(g.equals(a+h));//向上轉型爲Long
//結果
true
false
true
true
true
false
true
//反編譯
Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(2);
Integer c = Integer.valueOf(3);
Integer d = Integer.valueOf(3);
Integer e = Integer.valueOf(321);
Integer f = Integer.valueOf(321);
Long g = Long.valueOf(3L);
Long h = Long.valueOf(2L);
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c.intValue() == a.intValue() + b.intValue());
System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));
System.out.println(g.longValue() == (long)(a.intValue() + b.intValue()));
System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
System.out.println(g.equals(Long.valueOf((long)a.intValue() + h.longValue())));

//Long的equals
public boolean equals(Object obj) {
    if (obj instanceof Long) {//類型不同即是false
        return value == ((Long)obj).longValue();
    }
    return false;
}
包裝類型的大小比較

包裝類型使用時注意點

謹慎包裝類型的大小比較

public static void main(String[] args) {
    Integer i = new Integer(100);
    Integer j = new Integer(100);
    // Integer j = 100;(或者如此)
    compare(i,j);
}
//比較兩個包裝對象大小
public static void  compare(Integer i , Integer j) {
    System.out.println(i == j);
    System.out.println(i > j);
    System.out.println(i < j);
}
//結果
false
false
false
public static void main(String[] args) {
    Integer i = new Integer(100);
    Integer j = new Integer(100);
    // Integer j = 100;(或者如此)
    compare(i,j);
}
//比較兩個包裝對象大小
public static void  compare(Integer i , int j) {
    System.out.println(i == j);
    System.out.println(i > j);
    System.out.println(i < j);
}
//結果
true
false
false

提防包裝類型的null值

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(null);
    System.out.println(f(list));
}

public static int f(List<Integer> list) {
    int count = 0;
    for (Integer i : list) {
        //必須對null進行處理
        //count += (i!=null)?i:0;
        count += i;
    }
    return count;
}
//結果
Exception in thread "main" java.lang.NullPointerException
相關文章
相關標籤/搜索