This one of the frequently asked questions in interview. This question is frequently asked in 'C', but sometimes in 'Java' also.
What is the output of the program?
int i = 0;
i = i++;
System.out.println(i);
In C language, Dennis Ritchie has mentioned in the book "
The C Programming Language", the behaviour is undefined and left to implementations. But most of the implementations produce the result as '0'.
Let us see, what will be the output in 'Java'?
When the questions is asked to many people, they immediately said the answer as '1'. They gave the following explanation.
This is wrong.The line
i=i++;
is equivalent to
i=i;
i++;
That is, the value of i(0) is stored in the LHS, i.e. 'i'. Then the value of 'i' is incremented to '1' and then stored in 'i' and hence the result '1'.
Unfortunately, the answer is wrong. Let us see the reason.
i++ means post increment. It means, the value will be incremented after the operation is performed on it. It doesnt mean, the statement will be completed before execution. That is the value of the variable 'i' will be stored in a temporary location, then the value is incremented and then, the actual operation is performed, in this case assignment, on the value in the temporary location.
Hence,
i = i++;
is equivalent to,
int temp = i; // temp = 0
i++; // i=1
i = temp; // i = 0
Hence we get the result as '0'.
To get a clear understanding, let us look at the byte code for this operation.
public class Increment {
public static void main(String[] args) {
int i=0;
i=i++;
// System.out.println(i); // commented out to avoid unnecessary lines
}
}
Compile the file 'Increment.java'.
Java Byte Code:In the command line, type,
> javap -c Increment
This will display the methods and the byte code for the Increment class. The byte code will be displayed in the form of mnemonics - human readable form.
The following lines will be printed:
C:\Projects\test\src>javap -c Increment
Compiled from "Increment.java"
public class Increment extends java.lang.Object{
public Increment();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()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
}
Let us concentrate on the byte code for the main method. Before getting in to this problem, you should have a good understanding about the
Java Virtual Machine architecture.
Let us just have a brief introduction about Java Virtual Machine.
Java Virtual MachineThe JVM is Stack Based. That is, for each operation, the data will be pushed into the stack and from the stack the data will popped out to perform the operation. There is another data structure, typically an array to store the local variables.
The local variables are given ids which are just the index to the array. For a non-static method, 'this' reference will be at the array index '0', followed by method parameters and then the other local variables. For static methods, the parameters will start with '0' followed by local variables.
Program IllustrationLet us look at the mnemonics in main() method line by line.
Stack and Local Variables Array before the start of main() method.
| | args i
|---| --------------
| | | | |
|---| --------------
|___|
Stack Local Variable
0: iconst_0The constant value '0' is pushed to the stack.
| | args i
|-----| --------------
| | | | |
|-----| --------------
| 0 |
-----
Stack Local Variable
1: istore_1The top element of the stack is popped out and stored in the local variable with index '1'. That is 'i'.
| | args i
|-----| --------------
| | | | 0 |
|-----| --------------
| |
-----
Stack Local Variable
2: iload_1The value at the location 1, is pushed into the stack.
| | args i
|-----| --------------
| | | | 0 |
|-----| --------------
| 0 |
-----
Stack Local Variable
3: iinc 1, 1The value at the memory location '1' is incremented by '1'.
| | args i
|-----| --------------
| | | | 1 |
|-----| --------------
| 0 |
-----
Stack Local Variable
6: istore_1The value at the top of the stack is stored to the memory location '1'. That is '0' is assigned to 'i'.
| | args i
|-----| --------------
| | | | 0 |
|-----| --------------
| |
-----
Stack Local Variable
Hence, we get the result as '0', and not '1'.
Unlike C/C++, this behaviour is guaranteed in Java.
I think this article will give a good insight about the Java Language and the Java VM.