不用==用equals引發的一系列思考

畢業剛工作的時候,帶我的小師傅給我說判斷相等使用equals不要使用==,第一次寫java的我照辦了,但是不清楚爲什麼,之後還是決定真正瞭解一下java本身。於是開始看jdk源碼。這裏以Integer爲例

equal

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

可以看到equals方式是對Integer的內容進行比較,用equals確實沒有問題

那==是怎麼回事呢?

一般都知道在各類語言中都來比對地址的,不讓用我可以理解,但是爲什麼在項目中又看到有人用到呢?並且也沒什麼問題?地址是一樣的?不過不應該啊,於是開始看Integer在java中賦值過程是怎麼回事
java中Integer的賦值過程。

  Integer integer1=123;

看字節碼文件發現
在這裏插入圖片描述可以看到Integer是調用了Integer.valueof來賦值的,追蹤源碼

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

點開源碼一下就瞭解怎麼回事了,這不就是工作中緩存熱點數據麼。
原來它會在內存中緩存一份熱點數據-127-128,賦值過來如果在這個範圍內直接返回對應座標下的對象。所以說我們的數據只要在設置的範圍內,我們拿到的都說一個對象,地址當然相同,用==判斷一定也沒有問題。
又大概看了一下其他基礎類型的包裝類Long、Byte、Short都是類似設計,
Double、float直接創建新對象

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