为什么会进入无限循环?

本文翻译自:Why does this go into an infinite loop?

I have the following code: 我有以下代码:

public class Tests {
    public static void main(String[] args) throws Exception {
        int x = 0;
        while(x<3) {
            x = x++;
            System.out.println(x);
        }
    }
}

We know he should have writen just x++ or x=x+1 , but on x = x++ it should first attribute x to itself, and later increment it. 我们知道他应该只写x++x=x+1 ,但是在x = x++它应该首先将x归属于它自己,然后再增加它。 Why does x continue with 0 as value? 为什么x继续为0作为值?

--update --update

Here's the bytecode: 这是字节码:

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

}

I'll read about the instructions to try to understand... 我会读到有关试图理解的说明 ......


#1楼

参考:https://stackoom.com/question/G4hp/为什么会进入无限循环


#2楼

Check the below code, 检查以下代码,

    int x=0;
    int temp=x++;
    System.out.println("temp = "+temp);
    x = temp;
    System.out.println("x = "+x);

the output will be, 输出将是,

temp = 0
x = 0

post increment means increment the value and return the value before the increment . post increment意味着递增值并在递增之前返回值 That is why the value temp is 0 . 这就是值temp0 So what if temp = i and this is in a loop (except for the first line of code). 那么如果temp = i并且这是一个循环(第一行代码除外)。 just like in the question !!!! 就像在问题!!!!


#3楼

This statement: 这个说法:

x = x++;

evaluates like this: 评估如下:

  1. Push x onto the stack; x推入堆栈;
  2. Increment x ; 增量x ;
  3. Pop x from the stack. 从堆栈弹出x

So the value is unchanged. 所以价值没有变化。 Compare that to: 比较一下:

x = ++x;

which evaluates as: 评估为:

  1. Increment x ; 增量x ;
  2. Push x onto the stack; x推入堆栈;
  3. Pop x from the stack. 从堆栈弹出x

What you want is: 你想要的是:

while (x < 3) {
  x++;
  System.out.println(x);
}

#4楼

This is because it never gets incremented in this case. 这是因为在这种情况下它永远不会增加。 x++ will use the value of it first before incrementing like on this case it will be like: 在增加之前, x++将首先使用它的值,就像在这种情况下它会像:

x = 0;

But if you do ++x; 但是如果你做++x; this will increase. 这会增加。


#5楼

x = x++ works in the following way: x = x++以下列方式工作:

  • First it evaluates expression x++ . 首先,它评估表达式x++ Evaluation of this expression produces an expression value (which is the value of x before increment) and increments x . 对该表达式的求值产生表达式值(在递增之前是x的值)并且递增x
  • Later it assigns the expression value to x , overwriting incremented value. 稍后它将表达式值赋给x ,覆盖递增的值。

So, the sequence of events looks like follows (it's an actual decompiled bytecode, as produced by javap -c , with my comments): 因此,事件序列如下所示(它是一个实际的反编译字节码,由javap -c ,带有我的注释):

8:   iload_1         // Remember current value of x in the stack
   9:   iinc    1, 1    // Increment x (doesn't change the stack)
   12:  istore_1        // Write remebered value from the stack to x

For comparison, x = ++x : 为了比较, x = ++x

8:   iinc    1, 1    // Increment x
   11:  iload_1         // Push value of x onto stack
   12:  istore_1        // Pop value from the stack to x

#6楼

This happens because the value of x doesn't get incremented at all. 发生这种情况是因为x的值根本没有增加。

x = x++;

is equivalent to 相当于

int temp = x;
x++;
x = temp;

Explanation: 说明:

Let's look at the byte code for this operation. 我们来看看这个操作的字节代码。 Consider a sample class: 考虑一个示例类:

class test {
    public static void main(String[] args) {
        int i=0;
        i=i++;
    }
}

Now running the class disassembler on this we get: 现在运行类反汇编程序,我们得到:

$ javap -c test
Compiled from "test.java"
class test extends java.lang.Object{
test();
  Code:
   0:    aload_0
   1:    invokespecial    #1; //Method java/lang/Object."<init>":()V
   4:    return

public static void main(java.lang.String[]);
  Code:
   0:    iconst_0
   1:    istore_1
   2:    iload_1
   3:    iinc    1, 1
   6:    istore_1
   7:    return
}

Now the Java VM is stack based which means for each operation, the data will be pushed onto the stack and from the stack, the data will pop out to perform the operation. 现在Java VM是基于堆栈的,这意味着对于每个操作,数据将被推送到堆栈和堆栈,数据将弹出以执行操作。 There is also another data structure, typically an array to store the local variables. 还有另一种数据结构,通常是用于存储局部变量的数组。 The local variables are given ids which are just the indexes to the array. 局部变量给出id,它们只是数组的索引。

Let us look at the mnemonics in main() method: 让我们看看main()方法中的助记符

  • iconst_0 : The constant value 0 is pushed on to the stack. iconst_0 :常量值0被推入堆栈。
  • istore_1 : The top element of the stack is popped out and stored in the local variable with index 1 istore_1 :弹出堆栈的顶部元素并将其存储在索引为1的局部变量中
    which is x . 这是x
  • iload_1 : The value at the location 1 that is the value of x which is 0 , is pushed into the stack. iload_1 :位置1的值x0的值,被推入堆栈。
  • iinc 1, 1 : The value at the memory location 1 is incremented by 1 . iinc 1, 1 :存储位置1值增加1 So x now becomes 1 . 所以x现在变为1
  • istore_1 : The value at the top of the stack is stored to the memory location 1 . istore_1 :堆栈顶部的值存储在内存位置1 That is 0 is assigned to x overwriting its incremented value. 0指定给x 覆盖其递增的值。

Hence the value of x does not change resulting in the infinite loop. 因此, x的值不会改变,从而导致无限循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值