Integer類詳解

問題一:
一直很好奇一件事,類似於Integer i = 15; String s = “aa”;之類的代碼是怎麼實現的?
Integer和String是一個類,i,s是對應的對象,對象的創建需要new出來(不討論反射),但是上面的對象怎麼創建的?
於是去找Integer的構造函數,在第849行找到了。。。(構造函數不都放在前面麼),如下:

private final int value;
public Integer(int value) {
        this.value = value;
    }
public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }

只此兩個構造函數,一個傳入int形參,一個傳入String形參。還是沒解決問題!按理說應該且必須類似於new Integer(10);這樣創建對象啊!!
於是在Integer類中搜索"new Integer("字樣。一共搜索到了兩處,一處在內部類IntegerCache中出現,一處在public static Integer valueOf(int i){}方法體中出現,並且該方法體中出現了IntegerCache內部類,更神奇的是內部類IntegerCache只在該方法體中出現,於是得出結論:該內部類就是爲該方法而創建。於是分析一下這個ValueOf(int i)方法:

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

看到最後一個return語句,那肯定可以通過valueOf這個靜態方法創建對象,實驗一下果然成功了。
所以Integer只有兩種方式創建對象:直接創建和間接創建。①new Integer(10) ②Integer.valueOf(10)。開頭那種神奇的方法是用哪一種??
於是通過反編譯工具將代碼生成java文件後,神奇發現Integer i = 10變成了Integer i = Integer.valueOf(10);
所以問題解決了,編譯器將代碼處理成了valueOf方法去創建對象!!


問題二:
好像沒什麼問題了,想了想爲什麼編譯器不直接處理成new integer(10);上文可說了有兩種創建對象的方法,那個內部類是幹什麼用的?還專門爲valueOf(int i)方法創建一個內部類?

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

再看這個方法,只有i值在[IntegerCache.low, IntegerCache.high]範圍內纔會調用內部類創建對象,並且返回的是類成員變量cache數組的一個值,那這個數組裏面肯定就是存的對象咯。再看看這個內部類。

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() {}
    }

讀完意思就是:類靜態變量cache存儲-128到127之間的Integer對象,靜態代碼塊已經初始化好了。
也就意味着valueOf(int i)中i在-128到127之間時,直接去cache中根據下標取對象就行,對象已經創建好了。

問題三:
那?這是何必呢?是不是還意味着Integer a = 10; Integer b = 10;後a和b是同一個對象呢?不知道。用==號實驗一下,果然,結果是ture!
那麼用意何在?
個人猜測是爲了避免反覆創建-128到127之間的相同對象吧。那。那也創建了256個對象?能節約內存?

常用方法:

① int轉Integer

public int intValue() {
        return value;
    }

② String轉Integer

//若字符串中有非數字則拋異常
public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }

③ Integer轉其他七個基本數據類型

public byte byteValue() {
        return (byte)value;
    }

public short shortValue() {
    return (short)value;
}

public int intValue() {
    return value;
}

public long longValue() {
    return (long)value;
}

public float floatValue() {
    return (float)value;
}

public double doubleValue() {
    return (double)value;
}

public String toString() {
    return toString(value);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章