Java_語法基礎_優先使用整型池

例:

package deep;

import java.util.Scanner;

public class Client {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNextInt()) {
            int ii = input.nextInt();
            System.out.println("====" + ii + "的相等判斷====");
            // 兩個通過new產生的Integer對象
            Integer i = new Integer(ii);
            Integer j = new Integer(ii);
            System.out.println("new產生的對象:" + (i == j));

            // 基本類型轉爲包裝類型後比較
            i = ii;
            j = ii;
            System.out.println("基本類型轉換的對象:" + (i == j));

            // 通過靜態方法生成一個實例
            i = Integer.valueOf(ii);
            j = Integer.valueOf(ii);
            System.out.println("valueOf產生的對象:" + (i == j));
        }
    }
}

運行結果:
127
====127的相等判斷====
new產生的對象:false
基本類型轉換的對象:true
valueOf產生的對象:true
128
====128的相等判斷====
new產生的對象:false
基本類型轉換的對象:false
valueOf產生的對象:false
555
====555的相等判斷====
new產生的對象:false
基本類型轉換的對象:false
valueOf產生的對象:false

很不可思議呀,數字127的比較結果竟然與其他兩個數字不同,它的裝箱動作所產生的對象竟然是同一個對象,valueOf產生的也是同一個對象,但是大於127的數字128和555在比較過程中所產生的卻不是同一個對象,這是爲什麼?我們一個一個來解釋:
(1)new產生的Integer對象
new聲明的就是要生成一個新的對象,沒二話,這是兩個對象,地址肯定不等,比較結果爲false。
(2)裝箱生成的對象
對於這一點,首先要說明的是裝箱動作是通過valueOf方法實現的,也就是說後兩個算法是相同的,那結果肯定也是一樣的,現在的問題是:valueOf是如何生成對象的呢?我們來閱讀以下Integer.valueOf的實現代碼:

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

    /**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

以上代碼的意思已經很明瞭了,如果是-128到127之間的int類型轉換爲Integer對象,則直接從cache數組中獲得,cache是IntegerCache內部類的一個靜態數組,容納的是-128到127之間的Integer對象。通過valueOf產生包裝對象時,如果int參數在-128和127之間,則直接從整型池中獲得對象,不在該範圍的int類型則通過new生成包裝對象。
明白了這一點,要理解上面的輸出結果就迎刃而解了,127的包裝對象是直接從整型池中獲得的,不管你輸入多少次127這個數字,獲得的對象都是同一個,那地址當然都是相等的。而128、555超出了整型池範圍,是通過new產生一個新的對象,地址不同,當然也就不相等了。
以上的解釋也就是整型池的原來,整型池的存在不僅僅提高了系統性能,同時也節約了內存空間,這也是我們使用整型池的原因,也就是在聲明包裝對象的時候使用valueOf生成,而不是通過構造函數來生成的原因。順便提醒大家,在判斷對象是否相等的時候,最好是用equals方法,避免用“==”產生非預期結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章