5. 原生類型與封箱類

原生類型與封箱類

八個原生數據類型與void,與他們的箱

byte Byte
short Short
char Character
int Integer
float Float
long Long
double Double

boolean Boolean

void Void

在jdk的原碼中,能夠找到Class.getPrimitiveClass一共在九個地方使用過,正好是上面的九個類型。前八個是數據原生類型,後面的void通常用不到。對應的叫他們的封裝類型,也能夠叫他們是,而原生與箱之間的轉換分別叫作封箱拆箱html

出現的場景

int a1 = new Integer(10); //拆箱, 拆了new Integer(10)的箱成int類型,對應Integer.inValue();
Integer a2 = 100; //封箱,封了100的箱成Integer類,對應Integer.valueOf(…)

相關的操做由編譯器來完成,這能夠用javap來反編譯查看,具體能夠查看這片文章。 封箱與拆箱之間,會形成損耗,能夠看看這篇文章java

封裝類

Boolean只有兩個值,true與false,因此內部代碼也簡單。git

public class Mutax {
    public static void main(String[] args) {
        Boolean a1 = true;   //封箱。調用Boolean.valueOf(true)方法,在方法中返回的是Boolean.True;
        Boolean a2 = true;   //封箱。一樣是調用Boolean.valueOf(true)方法,因此返回對象是同樣的
        Boolean a3 = new Boolean(true); //不是Boolean.True,雖然也是true;
        boolean a4 = true;   
        boolean a5 = new Boolean(true); //拆箱,爲true值。

        System.out.println(a1 == a2);   // 對象相同,true
        System.out.println(a1 == a3);   // 對象不一樣,false
        System.out.println(a1 == Boolean.TRUE); //對象相同,true

        System.out.println(a3 == a4);   // a4爲原生類型,a4拆箱。true;
        System.out.println(a3 == a5);   // a5已是拆箱以後的原生類型,因此也是true;
    }
}

Character是操做字符集,utf-8中還包括漢字等,在其中漢字對應的UnicodeBlockCJK,CJK是Chinese、Japanese、Korean三個國家的文字。Character內部類CharacterCache中有128個緩存,因此也會出現你們都知道的相似Integer的緩存效果。segmentfault

public class Malix {
    public static void main(String[] args) {
        Character c1 = 127; //封箱,Character.valueOf(),由於小於128,因此會調用內部緩存中的數據
        Character c2 = 127; //封箱,同上
        Character c3 = 129; //封箱,大於128,不會調用緩存
        Character c4 = 129; //同上
        System.out.println(c1 == c2);  //true
        System.out.println(c3 == c4);  //false
    }
}

由於是對utf-8字符集操做,會有些想不到的效果。緩存

public class Kalax {
    public static void main(String[] args) {
        System.out.println(Character.isDigit('1')); 
        System.out.println(Character.isDigit(1));
        System.out.println(Character.isDigit(53));
    }
}

結果分別是true,false,true。 爲何?1不是數字反而53是?由於53的ascii碼中對應5,utf-8兼容着ascii,因此出現這種結果。code

Byte、Short、Integer、Long、Float、Double爲數值類型,繼承了Number抽象類。htm

public abstract class Number implements java.io.Serializable {
    public abstract int intValue();
    public abstract long longValue();
    public abstract float floatValue();
    public abstract double doubleValue();
    public byte byteValue() { return (byte)intValue();}
    public short shortValue() { return (short)intValue();}

}

因此這六個類中均可以轉其餘類。而他們拆箱的時候,調用的就是對應的方法。 六個類中,都有緩存128個緩存,可是Integer與其餘不一樣對象

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) {
                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);
            }
            high = h;

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

        private IntegerCache() {}
    }

能夠經過-XX:AutoBoxCacheMax=300來修改Integer中的緩存大小,若是加上了這個參數,下面的程序結果就不同了blog

public class Intex {
    public static void main(String[] args) {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;

        System.out.println(i1 == i2);// true
        System.out.println(i3 == i4);//加上-XX:AutoBoxCacheMax=300就是true,不加就是false
    }
}
相關文章
相關標籤/搜索