为什么会进入无限循环?

问题:

我有以下代码:

public class Tests {
    public static void main(String[] args) throws Exception {
        int x = 0;
        while(x<3) {
            x = x++;
            System.out.println(x);
        }
    }
}
&#91;/code&#93;
我们知道他应该只写<code>x++</code>或<code>x=x+1</code>,但是<code>x = x++</code>应该首先将<code>x</code>归因于自身,然后增加它。为什么<code>x</code>继续<code>0</code>为价值?
 <strong>--update</strong>
这是字节码:

public class Tests extends java.lang.Object{
public Tests();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iconst_3
   4:   if_icmpge   22
   7:   iload_1
   8:   iinc    1, 1
   11:  istore_1
   12:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   15:  iload_1
   16:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   19:  goto    2
   22:  return

}

我会阅读关于instructions来试图理解...

回答:

 注意:由于C#允许您通过引用ref关键字传递int参数,所以本来我在此答案中发布了C#代码。我已经决定使用我在Google找到的第一个MutableInt类来使用实际的合法Java代码进行更新,以排序哪些ref在C#中。我真的不知道这是否有帮助或伤害了答案。我会说我个人没有这么做Java开发;所以我知道,可以用更多的惯用方式来说明这一点。
也许如果我们写出一个方法来做相当于x++这样做会更清楚的方法。

public MutableInt postIncrement(MutableInt x) {
    int valueBeforeIncrement = x.intValue();
    x.add(1);
    return new MutableInt(valueBeforeIncrement);
}

对?增加传递的值并返回原始值:这是postincrement运算符的定义。
现在,我们来看看你的示例代码中的这种行为是如何发生的:

MutableInt x = new MutableInt();
x = postIncrement(x);

 postIncrement(x)做什么?增量x,是的。然后返回什么。然后将此返回值分配给x
因此,分配给x的值的顺序为0,则为1,则为0。
如果我们重写以上,这可能会更清楚:

MutableInt x = new MutableInt();    // x is 0.
MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.
x = temp;                           // Now x is 0 again.

您的注意事项是,当您使用y替换上述作业左侧的x时,您可以看到它首先将x递增,然后将其归因于y“使我感到困惑。不是x被分配到y;是以前分配给的值。真的,注射y使事情与上述情况没有区别;我们只是得到:

MutableInt x = new MutableInt();    // x is 0.
MutableInt y = new MutableInt();    // y is 0.
MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.
y = temp;                           // y is still 0.

所以很清楚:x = x++有效地不改变x的值。它总是使x具有值x 0,然后x 0 + 1,然后x 0
 更新:顺便提一下,为避免x被赋予1“之间的增量操作和上面的例子中的赋值,我已经汇总了一个快速演示来说明这个中间值确实存在,“虽然在执行的线程上永远不会被”看到“。
演示在循环中调用x = x++;,而单独的线程将持续将x的值打印到控制台。

public class Main {
    public static volatile int x = 0;

    public static void main(String[] args) {
        LoopingThread t = new LoopingThread();
        System.out.println("Starting background thread...");
        t.start();

        while (true) {
            x = x++;
        }
    }
}

class LoopingThread extends Thread {
    public @Override void run() {
        while (true) {
            System.out.println(Main.x);
        }
    }
}

以下是上述程序输出的摘录。注意1s和0s的不规则发生。

Starting background thread...
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
0
1

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Why does this go into an infinite loop?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 1 = 1