foreach寫失效的問題

本文由做者張遠道受權網易雲社區發佈。java

坦白講身爲程序員,bug在所不免。有人講,bug越多,說明程序員越偉大。這句話有它必定的道理。程序員

由於從某方面講,bug多了說明他的代碼量也多。數據庫

言歸正傳,這裏我記錄了我曾經犯過的幾個錯誤。但願看到的同儕可以見而避之。緩存

經常使用的一個場景,遍歷一個集合,對符合某種條件的元素作修改。習慣性地會寫出以下代碼:安全

List testInt = new ArrayList();
 testInt.add(1);
 testInt.add(2);
 testInt.add(3);     for(Integer temp :testInt ){      if(temp==1)
     temp=temp*2;
 }   
 for(Integer a:testInt ){
  System.err.println(a);
 }

期待的結果是:服務器

2oracle

2翻譯

3code

但實際輸出爲:對象

1

2

3

這是很容易掉進去的陷阱。即經過foreach遍歷對集合元素進行修改。在覺得變動已發生的時候,

其實變動沒有發生。形成數據寫入失敗。

由於

for(Integer temp:testInt){     if(temp==1)
    temp=temp*2;
}

將被翻譯成

for(int i=0,length=testStr.size();i<length;i++){

    Integer temp = testStr.get(i).clone();

    if(temp==1)

    temp=temp*2;

}

根據oracle的官方文檔,正式翻譯應該以下

for (Iteratori = testInt.iterator(); i.hasNext(); ) {            float i0 = (Integer)i.next();            if(i0 == 1)
            i0 = i0*2;
    }

即,foreach裏頭的的 temp變量只是一個局部變量,並且仍是集合中元素的一個副本,並非元素自己。

想到以前還遇到的一個問題,代碼簡化以下:

Integer integer1 = 3;
    Integer integer2 = 3;        if (integer1 == integer2)
        System.out.println("integer1 == integer2");        else
        System.out.println("integer1 != integer2");

    Integer integer3 = 300;
    Integer integer4 = 300;        
    if (integer3 == integer4)
        System.out.println("integer3 == integer4");        else
        System.out.println("integer3 != integer4");

即在判斷整數相等時,使用了封裝類(由數據庫映射過來,用封裝類防止反射異常)。實際的輸出結果以下:

integer1 == integer2

integer3 != integer4

明眼人很容易看出來,這裏掉入了兩個坑.一個坑是用等號判斷相等,除非是爲了比較同一個對象,等值比較不該該直接用等號。 另外一個坑是

java的整數緩存。

查看jdk的源碼以下:

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

即整數緩存緩存了前127個整數,沒有從新生成。

固然,還遇到其它各類各樣的坑。可怕的不是掉入坑中,而是掉入坑裏了不正視問題也不查找問題所在,一而再再而三地掉進坑裏。

免費領取驗證碼、內容安全、短信發送、直播點播體驗包及雲服務器等套餐

更多網易技術、產品、運營經驗分享請訪問網易雲社區。

文章來源: 網易雲社區

相關文章
相關標籤/搜索