资讯专栏INFORMATION COLUMN

foreach写失效的问题

MingjunYang / 1599人阅读

摘要:在以为变更已发生的时候,其实变更没有发生。造成数据写入失败。免费领取验证码内容安全短信发送直播点播体验包及云服务器等套餐更多网易技术产品运营经验分享请访问网易云社区。文章来源网易云社区

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

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

根据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://www.ucloud.cn/yun/25358.html

相关文章

  • 前端兼容性问题总结

    摘要:篇样式兼容性问题按模式渲染按模式渲染怪异模式怪异模式是没有遵守规范的一种兼容模式,其中的是包括左右左右在内的全部范围也一样,类似于,而且的不能从父元素继承。 HTML 篇 样式兼容性问题 怪异模式 怪异模式是没有遵守 W3C 规范的一种兼容模式,其中的 width 是包括 contentWidth, 左右padding, 左右border 在内的全部范围(height 也一样)...

    gghyoo 评论0 收藏0
  • 前端兼容性问题总结

    摘要:篇样式兼容性问题按模式渲染按模式渲染怪异模式怪异模式是没有遵守规范的一种兼容模式,其中的是包括左右左右在内的全部范围也一样,类似于,而且的不能从父元素继承。 HTML 篇 样式兼容性问题 怪异模式 怪异模式是没有遵守 W3C 规范的一种兼容模式,其中的 width 是包括 contentWidth, 左右padding, 左右border 在内的全部范围(height 也一样)...

    骞讳护 评论0 收藏0
  • 前端兼容性问题总结

    摘要:篇样式兼容性问题按模式渲染按模式渲染怪异模式怪异模式是没有遵守规范的一种兼容模式,其中的是包括左右左右在内的全部范围也一样,类似于,而且的不能从父元素继承。 HTML 篇 样式兼容性问题 怪异模式 怪异模式是没有遵守 W3C 规范的一种兼容模式,其中的 width 是包括 contentWidth, 左右padding, 左右border 在内的全部范围(height 也一样)...

    caikeal 评论0 收藏0
  • 数组遍历你都会用了,那Promise版本

    摘要:我们要进行一个奇数的筛选,所以我们这么写然后我们改为版本这会导致我们的筛选功能失效,因为的返回值匹配不是完全相等的匹配,只要是返回值能转换为,就会被认定为通过筛选。 这里指的遍历方法包括:map、reduce、reduceRight、forEach、filter、some、every因为最近要进行了一些数据汇总,node版本已经是8.11.1了,所以直接写了个async/await的脚...

    zhangqh 评论0 收藏0

发表评论

0条评论

MingjunYang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<