爲什麼會進入無限循環?

本文翻譯自: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的值不會改變,從而導致無限循環。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章