int被定義為Integer,導致程序死循環,瞭解底層代碼有多重要

前言:春節期間,坐在公司加班,本以為可以坐在那看看日誌,打打遊戲,聊會天一天就過去了,突然加群裡我,為什麼我的任務執行了快一上午了,怎麼還是處理中。

我隨便應付說,可能是數據量大,執行時間長唄,過了2個小時還是沒執行完,立即查看日誌,發現一個Exception都沒有,在看看log中是否打印了執行完畢的輸出,發現沒有,立馬慌了。

當時真是腦袋翁的一下,這是啥問題,報個錯也行呀。在本地項目中跑跑試試看,還是沒發現問題,依舊不打印執行完畢的日誌。

那我就看看是不是判斷出問題了,在判斷的地方打印出前後比較的值,發現從128開始,128!=128,返回為false。

這是什麼情況?


int被定義為Integer,導致程序死循環,瞭解底層代碼有多重要

開始真的認為不可能呀,基本類型比較怎麼還出現false了呢。後來一看代碼。我把int定義成了Integer。瞬間明白了為什麼?

大家都知道Integer是有緩存的,當數值在-128~127之間,是從緩存中取數據。

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

所有給大家做一個測試

<code>public class IntegerTest {    static Map<string> first = new HashMap<>();    public void testNum(Integer num) {        System.out.println(first.get("count" )+ "//" + num);        System.out.println(Integer.valueOf(first.get("count")) == num);    }    public int pageCount() {        return 128;    }    public static void main(String[] args) {        IntegerTest t = new IntegerTest();        final int str = t.pageCount();        first.put("count", "127");        int f = Integer.valueOf(first.get("count"));        int ff = f + 1;        first.put("count", ff + "");        t.testNum(str);    }}/<string>/<code>

程序輸出

<code>128//128false/<code>

我們將上面的入參修改為int:

<code>public class IntegerTest {    static Map<string> first = new HashMap<>();    public void testNum(int num) {        System.out.println(first.get("count" )+ "//" + num);        System.out.println(Integer.valueOf(first.get("count")) == num);    }    public int pageCount() {        return 128;    }    public static void main(String[] args) {        IntegerTest t = new IntegerTest();        final int str = t.pageCount();        first.put("count", "127");        int f = Integer.valueOf(first.get("count"));        int ff = f + 1;        first.put("count", ff + "");        t.testNum(str);    }}/<string>/<code>

程序運行結果就正確了

<code>128//128true/<code>

總結:還好當時知道Integer的源碼,看見128之後,想到了Integer的緩存,不然真的得找一會原因了。當你在面臨壓力面前還能心裡不急躁的去找bug是辦不到的,所以平時還是需要看看源碼,另外,這純是一種馬虎行為,大家在平時開發一定要注意下。


分享到:


相關文章: