建议7: 警惕自增的陷阱

老师就说:自增有两种形式,分别是i++和++i,i++表示的是先赋值后加1,++i是先加1后赋值,这样理解了很多年也没出现问题,直到遇到如下代码,我才怀疑我的理解是不是错了:

 public class Client {
public static void main(String[] args) {
int count =0;
for(int i=0;i<10;i++){
count=count++;
}
System.out.println("count="+count);
}
}

这个程序输出的count等于几?是count自加10次吗?答案等于10?可以非常肯定地告诉你,答案错误!运行结果是count等于0。为什么呢?

count++是一个表达式,是有返回值的,它的返回值就是count自加前的值,Java对自加是这样处理的:首先把count的值(注意是值,不是引用)拷贝到一个临时变量区,然后对count变量加1,最后返回临时变量区的值。程序第一次循环时的详细处理步骤如下:

步骤1 JVM把count值(其值是0)拷贝到临时变量区。

步骤2 count值加1,这时候count的值是1。

步骤3 返回临时变量区的值,注意这个值是0,没修改过。

步骤4 返回值赋值给count,此时count值被重置成0。

“count=count++”这条语句可以按照如下代码来理解:

 public static int mockAdd(int count){
//先保存初始值
int temp =count;
//做自增操作
count = count+1;
//返回原始值
return temp;
}

于是第一次循环后count的值还是0,其他9次的循环也是一样的,最终你会发现count的值始终没有改变,仍然保持着最初的状态。

此例中代码作者的本意是希望count自增,所以想当然地认为赋值给自身就成了,不曾想掉到Java自增的陷阱中了。解决方法很简单,只要把“count=count++”修改为“count++”即可。

该问题在不同的语言环境有不同的实现: C++中“count=count++”与“count++”是等效的,而在PHP中则保持着与Java相同的处理方式。每种语言对自增的实现方式各不同,读者有兴趣可以多找几种语言测试一下,思考一下原理。

下次如果看到某人T恤上印着“i=i++”,千万不要鄙视他,记住,能够以不同的语言解释清楚这句话的人绝对不简单,应该表现出“如滔滔江水”般的敬仰,心理默念着“高人,绝世高人哪”。

[改善Java代码]警惕自增的陷阱的更多相关文章

  1. [改善Java代码]警惕泛型是不能协变和逆变的

    什么叫做协变(covariance)和逆变(contravariance)? 在变成语言的类型框架中,协变和逆变是指宽类型和窄类型在某种情况下(如参数,泛型,返回值)替换或交换的特性,简单的说,协变是 ...

  2. [改善Java代码]警惕数组的浅拷贝

    建议62:警惕数组的浅拷贝 一.分析  在日常工作中,我们会遇见很多数组的拷贝和复制的问题,但是在你使用系统提供的API进行编码的时候,无形中会留下浅拷贝的隐患. 二.场景  有这样一个例子,第一个箱 ...

  3. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  4. [改善Java代码]避开基本类型数组转换列表陷阱

    开发中经常用到Arrays和Collections这两个工具类. 在数组和列表之间进行切换.非常方便.但是也会遇到一些问题. 看代码: import java.util.Arrays; import ...

  5. [改善Java代码]减少HashMap中元素的数量

    在系统开发中我们经常会使用HashMap作为数据集容器,或者是用缓冲池来处理,一般很稳定,但偶尔也会出现内存溢出的问题(OutOfMemory错误),而且这经常是与HashMap有关的.而且这经常是与 ...

  6. [改善Java代码]不使用stop方法停止线程

    线程启动完毕后,在运行可能需要终止,Java提供的终止方法只有一个stop,但是不建议使用此方法,因为它有以下三个问题: (1)stop方法是过时的 从Java编码规则来说,已经过时的方式不建议采用. ...

  7. [改善Java代码]避免带有变长参数的方法重载

    建议4: 避免带有变长参数的方法重载 在项目和系统的开发中,为了提高方法的灵活度和可复用性,我们经常要传递不确定数量的参数到方法中,在Java 5之前常用的设计技巧就是把形参定义成Collection ...

  8. [改善Java代码]对字符串排序 持一种宽容的心态

    在Java中一涉及到中文处理就会冒出很多的问题来,其中的排序也是一个让人头疼的问题,看代码: import java.util.Arrays; public class Client { public ...

  9. [改善Java代码]推荐在复杂字符串操作中使用正则表达式

    一.分析  字符串的操作,诸如追加.合并.替换.倒序.分隔等,都是在编码过程中经常用到的,而且Java也提供了append.replace.reverse.split等方法来完成这些操作,它们使用起来 ...

随机推荐

  1. linux下开发c++第二弹--helloworld与makefile

    一:hello world sudo vim hello.cpp 输入  g++ -o hello hello.cpp  获得hello 输入  ./hello 运行,显示结果hello world! ...

  2. 【转】新建maven工程为什么jdk会是默认版本 而不是自己设置的版本?

    原文链接:为什么我eclipse新建项目的时候默认的是JRE1.5? 修改Maven中conf目录里的setting.xml文件内容,加上如下内容: <profiles> <!-- ...

  3. (转载)JDOM/XPATH编程指南

    JDOM/XPATH编程指南 本文分别介绍了 JDOM 和 XPATH,以及结合两者进行 XML 编程带来的好处. 前言 XML是一种优秀的数据打包和数据交换的形式,在当今XML大行于天下,如果没有听 ...

  4. Cognos报表打开参数

    查看门户页面 http://localhost:9300/p2pd/servlet/dispatch? b_action=xts.run &m=portal/cc.xts &gohom ...

  5. 当心回车符破坏你的JSON数据

    今天发现系统中一个地方获取JSON数据时,时而失败,时而成功,最后发现是回车符搞的鬼. 当你的JSON中有回车符时,会致使你的JSON出现格式错误:解决办法是在保存数据,或整理数据向客户端输出时将回车 ...

  6. [iOS微博项目 - 1.4] - 各种item NavigationBar & NavigationItem & BarButtonItem || TabBar & TabBarItem

    一.UINavigationItem1> 获得方式self.navigationItem // self是指控制器2> 作用可以用来设置当前控制器顶部导航栏的内容// 设置导航栏中间的内容 ...

  7. 面试之BI-SQL--table转换

    题目如下: Num 1 2 4 6 7 8 10 11 13 写条SQL语句转成下表: Column1  Column2 1              2 4              4 6     ...

  8. UVaLive 7374 Racing Gems (DP,LIS)

    题意:以辆赛车可以从x轴上任意点出发,他的水平速度允许他向每向上移动v个单位,就能向左或向右移动v/r个单位(也就是它的辐射范围是个等腰三角形) 现在赛车从x轴出发,问它在到达终点前能吃到的最多钻石. ...

  9. ORACLE R12 MOAC

    MOAC简介 MOAC(Multi-Org Access Control)为多组织访问控制,是Oracle EBS R12的重要新功能.它可以实现在一个Responsibility下对多个OU(Ope ...

  10. ArcGIS Add-in开发(一)--获取选定要素的属性值

    刚刚接触AE开发,记录一下自己的学习心得! 欢迎大家一起交流探讨! 最近做大赛,突然想到可以让项目更加直观的操作,就在项目中加了幅底图(底图很简单) 我想在arcmap中选中相应的要素后,在后台通过写 ...