foreach写失效的问题

本文由作者张远道授权网易云社区发布。

坦白讲身为程序员,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);
 }





期待的结果是:

2

2

3

但实际输出为:

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个整数,没有重新生成。

当然,还遇到其它各种各样的坑。可怕的不是掉入坑中,而是掉入坑里了不正视问题也不查找问题所在,一而再再而三地掉进坑里。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区。

文章来源: 网易云社区

    原文作者:网易云社区
    原文地址: https://segmentfault.com/a/1190000017375729
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞