本文翻译自: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
. 这就是值temp
为0
。 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: 评估如下:
- Push
x
onto the stack; 将x
推入堆栈; - Increment
x
; 增量x
; - Pop
x
from the stack. 从堆栈弹出x
。
So the value is unchanged. 所以价值没有变化。 Compare that to: 比较一下:
x = ++x;
which evaluates as: 评估为:
- Increment
x
; 增量x
; - Push
x
onto the stack; 将x
推入堆栈; - 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 ofx
before increment) and incrementsx
. 对该表达式的求值产生表达式值(在递增之前是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 value0
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 index1
istore_1
:弹出堆栈的顶部元素并将其存储在索引为1
的局部变量中
which isx
. 这是x
。 -
iload_1
: The value at the location1
that is the value ofx
which is0
, is pushed into the stack.iload_1
:位置1
的值x
是0
的值,被推入堆栈。 -
iinc 1, 1
: The value at the memory location1
is incremented by1
.iinc 1, 1
:存储位置1
值增加1
。 Sox
now becomes1
. 所以x
现在变为1
。 -
istore_1
: The value at the top of the stack is stored to the memory location1
.istore_1
:堆栈顶部的值存储在内存位置1
。 That is0
is assigned tox
overwriting its incremented value. 将0
指定给x
覆盖其递增的值。
Hence the value of x
does not change resulting in the infinite loop. 因此, x
的值不会改变,从而导致无限循环。