This question has already been answered:

There is a code:

int i = 1; i=i++; System.out.println(i); 

SUDDENLY

Output:1

Question: Why gives a unit? I think I should give a deuce. So what is the postfix notation? Even if it would first assign i unit, then it would still have to increase the value of i by one.

Ps. I want to get an answer in steps, like:

  1. At first, it does this because ...

  2. Then it does it because ...

Reported as a duplicate by user192664, aleksandr barakin , smellyshovel , user300000, kot-da-vinci on Oct 25 '18 at 17:14 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • @Denis not. In mechanics there are two sections - dynamics, it describes the joint position (the moon rotates around the earth) and kinematics (which the moon rotates around the earth). That question was answered in the context of the dynamics of why the author was satisfied, and here kinematics is required. - Andrew Kachalin
  • Why do you want it? I simply would not use such expressions: there is a possibility that the behavior may not be defined. At least as in C in the example int x = 5, y = 6; int z = x ++ + y ++; - Mikhail Ionkin
  • @MikhailIonkin I want to understand with one eye the whole project, right up to where there is a transistor in the gland. - Andrew Kachalin

7 answers 7

Perhaps it will be clearer at the bytecode level. Your code will be compiled into

  0: iconst_1 // Загрузить константу 1 в стек 1: istore_1 // Сохранить значение из стека в локальную переменную i 2: iload_1 // Загрузить значение локальной переменной i в стек (в стеке 1) 3: iinc 1, 1 // Увеличить значение локальной переменной i на 1 (в переменной теперь 2) 6: istore_1 // СОХРАНИТЬ ЗНАЧЕНИЕ ИЗ СТЕКА В ПЕРЕМЕННУЮ i (в переменной опять 1) 7: getstatic #2 10: iload_1 // Загрузить в стек значение переменной i 11: invokevirtual #3 // Вывести значение 

I did not find a specific description of this behavior in the Java Language Specification, but it does not contradict sections 15.14.2 and 15.26.1 describing the procedure for parsing postincrement expressions and assignment.

  • IMHO the most interesting. - Andrew Kachalin
  • 3
    This does not explain anything, but only shows the bytecode implementation. The explanation would be a quote from the appropriate Java Language Specification site. - Rostislav Red
  • Sogalsen, with Rostislav. I am trying to understand that something is not very good. Would explain on each team more deployed. Although still very interesting. - Andrew Kachalin 4:04 pm
  • @AndrewKachalin I also agree with Rostislav, but unfortunately I don’t remember by heart the JLS. - Sergey Gornostaev
 int i = 1; // вместо i = i++; int __temp = i; i = i + 1; i = __temp; System.out.println(i); 

What happens in the row

 i = i++; 

First, the right side is calculated. The value of i (equal to 1 ) is remembered. Then the value of i increased by one. Then the memorized value of 1 returned. Then assignment is made to the value 1 variable i .

This is the same as the other answers.

  • Here is the most interesting. And from what considerations is there a new temporary variable in this operation? - Andrew Kachalin
  • @AndrewKachalin This is what happens in your code. A new variable gets the compiler. - Igor
  • That is, at the compilation stage, the compiler translates the source code into an analogue of what you wrote? And what he uses the rule, can you explain? How does he see? - Andrew Kachalin
  • 2
    @AndrewKachalin afraid to explain the principles of the work of stack virtual machines can not fit in one answer. - Sergey Gornostaev
  • @AndrewKachalin I did not understand about the "rule"). - Igor

In your example, post-increment ( i++ ) is used; in this case, you first get the old value, and then add one to the current value ( ++ ). To get 2 you need to use pre-increment: ++i (please note the increment before the variable name).

  • one
    Unclear. Write down the equivalent, if you understand. - Andrew Kachalin

Look, this code:

  int i = 1; i = i++; int a = i; System.out.println(a + "" + i); int b = i++; System.out.println(b + "" + i); 

displays

 11 // обратите внимание, что i снова вернулось значение 1 12 // i уже равно 2, но b получает старое значение i 

that is, the expression N = i ++ really increases i by one, but the variable N will be assigned the value that i had before the increase — the postfix works according to this law.

The "highlight" in your question is that you really increased the variable i by one, but then "suddenly" assigned the same variable i to the value that was before the increase - and you again became equal to i variable 1.

The answer is “step by step”: the reason for such a result is as follows: first, an operation of incrementing i by one is done, and then an operation is performed on assigning the left variable to the value i, which was at the beginning. If the same variable is to the left and to the right, then the second operation naturally “overwrites” all previous operations.

     int i = 1; // i=1 i++ // i=2, значение выражения 1 i = ...; // присвоить 1 в переменную i - получается i=1 
    • one
      YaNifigaNone Understand - Andrew Kachalin
    • one
      Debugger in the teeth and debazh steps. - Qwertiy
    • 2
      "Debugger in the teeth and debazh on the steps" That's what I do not like Russian SO. - Andrew Kachalin
    • four
      @AndrewKachalin, I have written in the answer 3 steps: assign, make increment, assign. And I have no idea that in these three steps it may not be clear. - Qwertiy
    • The equivalent of the increment operation expressed in assembly language in the context of assigning a variable to itself is not clear. - Andrew Kachalin

    My friend first you need to understand how the operator ++ works

     int i = 1; OperatorPlusPlus(i); int OperatorPlusPlus(int yourNumber){ int tmp = yourNumber; int yourNumber = yourNumber + 1; return tmp; } 

    That is, you get the value of the variable tmp and i is equal to 2, then you i (2) the assignment of the value tmp (1)

    • int OperatorPlusPlus(int yourNumber){ and where can you find int yourNumber in the body? And if possible, please give a link to the source, that ++ works that way. - Andrew Kachalin
    • In fact, we did the wheel in a lesson using C ++, there is such a thing as operator overloading (I don’t know if it is in Java), with the help of it you can overload operators (++, +, -...) on with ++ I can throw off later - ost1m1ron -
    • + ost1m1ron you have an error in the loop body, you see? probably you need to replace yanmber. As for the implementation, it looks like I'm stupid. So many people understand how this works, and I don’t. - Andrew Kachalin
    • I wrote through the phone I apologize - ost1m1ron -
    • Example Example: operator ++ () {int tmp = this-> i; this-> i = this-> i + 1; return tmp; } was written in c ++ - ost1m1ron -

    Let's start with the basics of increment work.

    Take an example:

     int x = 1; int y = x++; System.out.println(y +""+x); 

    Output: 12

    In the first approximation it may seem that the following occurred in the second line:

    1. At first, the current value was assigned, the unit was written to the variable y .
    2. Then the variable x is increased by one.

    However, a closer look, says that everything was much more complicated. To do this, you need to look at the decompiled byte-code of the same example:

     byte x = 1; //int x = 1 - ориг. код byte var10000 = x; //2 строка ориг. кода int x1 = x + 1; //2 строка ориг. кода byte y = var10000; //2 строка ориг. кода System.out.println(y + "" + x1); 

    From it, you can easily see that the equivalent of the "simple" line is int y = x++; become three lines at once. It looks like they work as follows:

    1. First, the variable var10000 is allocated to which x is written;
    2. After the creation of the variable x1 in which the value increases by one.
    3. Next, the variable y is assigned the value var10000 - that is, the old value x .

      It turns out that the prefix increment contains the creation of two new variables.

    From the above, it is obvious that the original expression:

     int i = 1; i=i++; System.out.println(i); 

    in the decompiled byte code will look like:

      byte i = 1; //x заменили на i byte var10000 = i; int i1 = i + 1; i = var10000; //Мы по сути y заменили i System.out.println(i); 

    That is, the last operation before outputting to the console is an entry in the variable i of a temporary value. In accordance with the priority of operations , assignment is always performed after the increment / decrement.

    Ps . Additionally, a similar question was given 17! Answers in English stackflow .

    • 2
      It has nothing to do with the “priority of operations”. It is necessary to understand that all manipulations with the right side of the assignment operator are performed before assigning the left side. And that's all. - Igor
    • @Igor Really? That is, the priority of operations does not decide which operation to use in the first place? - Andrew Kachalin
    • @AndrewKachalin is not in this case. - Sergey Gornostaev