Let's take a look at the bytecode of the following program:
package A;
public class Test
{
public static void main(String[] args)
{
int a = 1;
a += (a = 2);
}
}
We just need to run this command:
javap -c Test.class
to get the following bytecode:
public class A.Test {
public A.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_1
1: istore_1
2: iload_1
3: iconst_2
4: dup
5: istore_1
6: iadd
7: istore_1
8: return
}
Explanation:
We will just focus on the two lines inside the main method:
int a = 1;
a += (a = 2);
[int a = 1; begins here]
0: iconst_1
- Pushes int
1 onto the stack.
-------------
| |
-------------
| |
-------------
| 1 |
-------------
STACK
1: istore_1
- Pops int value from the stack to
variable 1 (variable 1 represents a)
-------------
| | variable 1
------------- --------------
| | | 1 |
------------- --------------
| |
-------------
STACK
[int a = 1; finishes here]
[a += (a = 2); begins here]
2: iload_1
- Loads an int value from local
variable 1 and pushes it onto the stack.
-------------
| | variable 1
------------- --------------
| | | |
------------- --------------
| 1 |
-------------
STACK
3: iconst_2
- Pushes int
2 onto the stack.
-------------
| | variable 1
------------- --------------
| 2 | | |
------------- --------------
| 1 |
-------------
STACK
4: dup
- duplicate the value on top of the stack.
-------------
| 2 | variable 1
------------- --------------
| 2 | | |
------------- --------------
| 1 |
-------------
STACK
5: istore_1
- Pops int value from the stack to
variable 1.
-------------
| | variable 1
------------- --------------
| 2 | | 2 |
------------- --------------
| 1 |
-------------
STACK
6: iadd
- Adds the top two values together.
-------------
| | variable 1
------------- --------------
| | | 2 |
------------- --------------
| 3 |
-------------
STACK
7: istore_1
- Pops int value from the stack to
variable 1.
-------------
| | variable 1
------------- --------------
| | | 3 |
------------- --------------
| |
-------------
STACK
[a += (a = 2); finishes here]
8: return
Conclusion:
a = a + (a = 2) is done through several operations. 2: iload_1 is executed as first command of a += (a = 2); which reads the first operand of the equation a = a + (a = 2) and pushes onto the stack.
Next, 3: iconst_2 and 4: dup are executed which basically push int 2 twice onto the stack; one for loading it to a and the other as the second operand. After that, 5: istore_1 is executed which is loading 2 into a (a = 2).
Finally, 6: iadd and 7: istore_1 are executed where 6: iadd adds the first operand and the second operand and pushes the result onto the stack, and 7: istore_1 pops the result and loads it into a.
For simplicity, let's have a quick look at this code:
int a = 1;
int b = 3;
a += b;
and here is its bytecode:
public class A.Test {
public A.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_1
1: istore_1
2: iconst_3
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_1
8: return
}
As you can see, it simply does the following:
- Loads int
1 into a.
- Loads int
3 into b.
- Pushes
a then b onto the stack.
- Performs the addition on them and pushes the result onto the stack.
- Pops the result from the stack and stores it into
a.