黑马程序员技术交流社区

标题: 这个结果居然是0! [打印本页]

作者: 申绪胜    时间: 2011-12-19 09:31
标题: 这个结果居然是0!
public class Test
{       
        public static void main(String [] args)
        {

                int j = 0;
                for (int i = 0; i < 100; i++)
                {
                        j = j++;
                }
                System.out.println(j);
        }       
}
求高人指点一下 为什么结果是0
虽然是把j的本身赋值给自己,但是j还得自加1啊
作者: 刘健    时间: 2011-12-19 09:34
++是先赋值后+,所以j就一直被赋值为0
作者: 杨扬    时间: 2011-12-19 09:47
本帖最后由 杨扬 于 2011-12-19 10:00 编辑

j++的时候会重新为变量运算分配一块内存空间,以存放原始的值,而在完成了赋值运算之后,将这块内存释放掉。
假设 j 的地址为 000001,
在执行 j++的 会开辟一块新的内存出来 000002 保存 j 的原始值(也就是0,下例中的temp)
j = j++; 的时候 j 会+1 而000002里面的值会赋给j。

所以可以这么看成是
  1. for(int i=0;i<100;i++)
  2. {
  3.    int temp = j++;//temp=0;应为是j++,j把0赋给temp后才自己加
  4.    j = temp;//j=0;
  5.   
  6. }
复制代码

作者: 余松霖    时间: 2011-12-19 10:07
本帖最后由 余松霖 于 2011-12-19 10:16 编辑

首先刚开始J = 0 , 在J = J++的时候, 等号前面的那个J已经不是J声名时的那块内存区了,JVM为他重新为他分配一块新的内存区.
比如说,int j = 0 时,j的内存地址为00xx01,值为0。那么经过第一循环的以后前面那个J内存地址为00xx02,值为0,而后面那个J(内存地址00xx01)则会进行++操作,此时他的值为1,不过他已经不能影响到前面J的值了,此时J的内存地址就已经是等号前面的那个J的内存地址了(00xx02),再进行第二循环的时候,j的内存地址是:00xx02,值是0,至于00xx01那块内存区域,因为已经没有人再使用,所以将会在下一次垃圾回收的时候被GC回收,此时他(内存地址为00xx02的J)变成后面的那个j,前面那个J 则又会重新分得一块新的内存区域00xx03,值仍然是0,而00xx02则又会被丢弃然后被GC回收,依此类推,直至最后打印时J仍然为0,但他的内存地址已经不是最开初的00xx01了,

换句话说,他已经不是当初的那个J了。  所以说最后结果是0.
作者: 常兆鹏    时间: 2011-12-19 10:35
j初始值是0,j=j++是先给j赋值再执行j++。循环执行一次j=0,j++就被内存释放了,所以不论执行多少次结果都是0.
把前面的去掉,直接j++即可得到结果100.
作者: 刘旭    时间: 2011-12-19 10:36
j=j++;的意思是:先把右边的j赋值给左边的j,此时,j=0;然后,右边的j再加1.这相当于j在循环过程中先赋值,在加1。所以,在循环时,j移植等于0。
当将循环体改为j++;时,输出结果才为期望值。
作者: 梁俊    时间: 2011-12-19 11:15
好难懂啊
作者: 郭繁森    时间: 2011-12-19 11:50
                for (int i = 0; i < 100; i++)  //  i=0满足i<100,所以执行for内的执行语句
                {
                        j = j++;                //只是执行J++的动作,j=j+1,执行完,执行i++,再判断 i与100的大小,然后再执行  j++(先把j赋给j再自加)。可改为++j。
                }
                System.out.println(j);
}
楼上的各位已经讲了,应该能明白了吧
作者: 为梦而战    时间: 2011-12-19 15:43
j=j++;这条语句的意思是先赋值后++所以后加的值不会赋给J,这是运算符优先级造成的,j=j++和 j=j;j=j+1;是不一样的!
作者: 颜宗茂    时间: 2011-12-19 16:22
其实自增运算符谁先赋值和谁先自增很容易搞混,也就是运算符优先等级问题。j=j++;意思是:语句右边的j先赋值给左边的j然后自增1,但是j的值不变,还是原来初始化的值0;如果语句是:j=++j;意思是:语句右边的j先自增1然后再赋值给左边的j,这样左边j 的值会重新赋给j,这样在for循环语句中循环而自增。
作者: 房宝彬    时间: 2011-12-19 22:51
本帖最后由 房宝彬 于 2011-12-19 22:52 编辑

你这么理解就OK了

也不用上面说的那么复杂

首先 for循环表达式成立然后往下进行    j = j++;

进行这里的时候,是将 =号右边的  J   赋值=号左边的  j , 然后在将=号右边的 J 加1

这样就是不断的把 =号右边的“J”赋值给=号左边的“j”           懂了吧!
作者: 唐林渊    时间: 2011-12-20 08:58
哥们,一看都知道你没有仔细听毕老师的讲课,毕老师强调很多次,还举例说明了这样的问题       J=J++,先出去吃饭了,没有加1.   J=++J先吃饭后出去玩的。。。这个比喻有意思
作者: 冯瑞君老师    时间: 2011-12-20 09:35
j=j++;这条语句的意思是先赋值后,j=0;
然后,右边的j再加1  所以后加的值不会赋给J,for循环执行了一次j=0,j++就被内存释放了,所以不论执行多少次结果都是0。
作者: 荣凯旋    时间: 2011-12-20 09:47
楼主~我只是怀疑哥们你的技术分杂刷上去的~告诉我下白~{:soso_e110:}
作者: 付旭    时间: 2011-12-20 13:14
  为啥我复制代码  运行报错...  但是取消开头的public 就不报错了  为啥呢???
作者: 李栋    时间: 2011-12-20 15:51
付旭 发表于 2011-12-20 13:14
为啥我复制代码  运行报错...  但是取消开头的public 就不报错了  为啥呢??? ...

付旭同学,您看一下是不是class之前的public取消了
作者: 李栋    时间: 2011-12-20 15:52
我对这个为0的结果的解释完全看不懂啊······不知道毕老师视频中是否能够讲到啊
作者: 付旭    时间: 2011-12-20 17:22
李栋 发表于 2011-12-20 15:51
付旭同学,您看一下是不是class之前的public取消了

   是啊 ...  为啥呢?

作者: 武超    时间: 2011-12-20 18:04
这是一个赋值的问题,如果是x=j++你可能就知道了,这里是将x赋值为0之后将j加1;而j=j++就是将j赋值为0;然后再将j加1,j++;是执行的是变量的值,相当于j=j+1,并且将刚刚的J赋值给了它。因此j一直就是0;
改成j=j+1;或j++;都可正确运行
作者: 李栋    时间: 2011-12-20 20:35
付旭 发表于 2011-12-20 17:22
是啊 ...  为啥呢?

class之前加个public的话,是需要用那个类名命名文件名的,比如public class OkoO    那么命名就只能是OkoO    不能是Okoo    也就是OkoO.java    但是如果没有public    直接是class OkoO的话,那么就可以把文件名命名为okoo或者一切其他符合规范的名字,比如josdfijoej.java也可以。
作者: 付旭    时间: 2011-12-20 21:56
李栋 发表于 2011-12-20 20:35
class之前加个public的话,是需要用那个类名命名文件名的,比如public class OkoO    那么命名就只能是Ok ...

为啥加个public 文件名就要保持一致呢?  不加就可以随意呢?
作者: 李栋    时间: 2011-12-21 03:19
付旭 发表于 2011-12-20 21:56
为啥加个public 文件名就要保持一致呢?  不加就可以随意呢?

其实吧,这个问题就如同是为什么要写class定义类名是一个道理的,因为这个没有什么原因的呀,以后您只要看是否能用java运行,能的以后就那样做,不能就不那样做,如果一定要问为什么的话,那我估计会浪费很长时间并且根本找不到答案,同时也会对编程失去信心的:handshake
作者: 陈帅雷    时间: 2011-12-21 13:18
这多热心人,回复的挺详细的,{:soso_e100:}
作者: 周敏2011nc    时间: 2011-12-21 17:57
首先j = j++ 是会先赋值再自加,这也是问题的关键所在,你的j初始值为0,所以第一次循环后j = j++代码执行的结果是j 的值还是等零,依次类推你每次都把0赋给了j。这样即使你循环无数次j还是0
作者: 大梅    时间: 2011-12-21 19:51
每次赋的值都是自加之前的值也就是0,自加后得到的值变了,所以分配到的内存也不一样了,所以++进行在了原来的0上,一次循环下去。属于内存泄露吧,应该是




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2