为什么会进入无限循环?

我有以下代码:


public class Tests {

    public static void main(String[] args) throws Exception {

        int x = 0;

        while(x<3) {

            x = x++;

            System.out.println(x);

        }

    }

}

我们知道他应该只是写x++或者x=x+1,但是x = x++它首先要归于x自身,然后再增加它。为什么x继续0作为价值?


--update


这是字节码:


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


}

我会读到有关试图理解的说明 ......


手掌心
浏览 703回答 3
3回答

牛魔王的故事

注意:最初我在本答案中发布了C#代码用于说明,因为C#允许您int通过引用传递参数和ref关键字。我决定使用MutableInt我在Google上找到的第一个类来实际使用合法的Java代码来更新它,以便对refC#中的内容进行近似处理。我无法确定这是否有助于或伤害答案。我会说我个人没有做过那么多Java开发; 所以我知道可能有更多的惯用方法来说明这一点。也许如果我们写出一个方法来做相同的事情x++,它会使这更清楚。public MutableInt postIncrement(MutableInt x) {&nbsp; &nbsp; int valueBeforeIncrement = x.intValue();&nbsp; &nbsp; x.add(1);&nbsp; &nbsp; return new MutableInt(valueBeforeIncrement);}对?增加传递的值并返回原始值:这是postincrement运算符的定义。现在,让我们看看您的示例代码中这种行为是如何发挥作用的:MutableInt x = new MutableInt();x = postIncrement(x);postIncrement(x)做什么?增量x,是的。然后返回什么x 是增量之前。然后将此返回值分配给x。因此,赋值的值的顺序x为0,然后是1,然后是0。如果我们重写上述内容,这可能会更清楚:MutableInt x = new MutableInt();&nbsp; &nbsp; // x is 0.MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.x = temp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Now x is 0 again.当你x在上面的作业的左侧替换为y“你可以看到它首先递增x,然后将它归因于y” 这一事实时,你固定的事实让我感到困惑。它不是x被分配给y; 它是以前赋予的价值x。实际上,注入y使事情与上面的场景没有什么不同; 我们只是得到:MutableInt x = new MutableInt();&nbsp; &nbsp; // x is 0.MutableInt y = new MutableInt();&nbsp; &nbsp; // y is 0.MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.y = temp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// y is still 0.所以很清楚:x = x++有效地不会改变x的值。它总是使x的值为x 0,然后是x 0 + 1,然后再次为x 0。更新:顺便说一句,为了避免你怀疑x在上面的例子中增加操作和赋值之间的分配是1“之间”,我已经把一个快速演示组合在一起来说明这个中间值确实“存在”,尽管它会永远不会在执行线程上“看到”。演示调用x = x++;循环,而单独的线程连续打印x控制台的值。public class Main {&nbsp; &nbsp; public static volatile int x = 0;&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; LoopingThread t = new LoopingThread();&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Starting background thread...");&nbsp; &nbsp; &nbsp; &nbsp; t.start();&nbsp; &nbsp; &nbsp; &nbsp; while (true) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = x++;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}class LoopingThread extends Thread {&nbsp; &nbsp; public @Override void run() {&nbsp; &nbsp; &nbsp; &nbsp; while (true) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Main.x);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}以下是上述程序输出的摘录。注意1和0的不规则出现。启动后台线程...00110000000000101
打开App,查看更多内容
随时随地看视频慕课网APP