Tips and Tidbits from someone Sun felt was Certifiable

Today | ???common.rss??? | ???common.rdf??? | ???common.atom??? | ???common.other???
 
What is the output of executing the following code?
public class Test
{
    public static void main(String[] args)
    {
        int i = 0;
        i = i++;
        System.out.println(i);
    }
}

So, what's the answer? Many people are tempted to say that the answer is 1, but those folks are wrong. Don't believe me? Try it for yourself. This code will output 0.

This is a common trick that I see in a lot of SCJP mock exams. The key here is to understand how the post-increment operator works as well as the order in which expressions are evaluated. Let's look at the key line in this program:

i = i++;

Before we start executing this line, i is assigned the value 0. Before we can perform this assignment, we must evaluate the operands of the expression. The only operand to evaluate is "i++".

To evaluate i++, we first substitute the original value of i into the expression, which is 0, and then increment i to 1. That leaves us with this expression:

i = 0; // Meanwhile, i has been set to 1.

Of course, we now complete the assignment by assigning 0 to i, overwriting the increment that we had just completed.

Be wary when you spot this trick in a mock exam. It's one of those questions that a lot of people stumble over the first time, but never again.

Until next time,
Corey


I find that it's not a tricky question/concept. It just gets over analyzed by people preparing/taking the exam and they end up confusing themselves and getting it wrong. Is it nothing more then: Take what i is and assign it to i. Well i was zero and since a post operator is evaluated after the assignment, i stays zero. To REALLY make your point you should repeat your assignment and print lines. Because I bet some people think they get one in the 2nd print. Again, I really dig your blog.
Thanks, Erik. Like I said - this is a trick. It's a concept that is easily "overlooked" or "overanalyzed" by the people taking the exam. As I mentioned in the original thread, it's something people stumble over the first time and never again.

If nothing else, running across questions like this teaches you to pay close attention to details. Honestly, I think the hardest part of the SCJP exam is paying attention to details.
Erik, Can you blog some entries on floating point arthmetic and bitwise and shift operators. Thanks, Raj
Sorry, I meant Cory.
Nice entry. This is one that always catches my classes, even after a full day of discussion. Thats why I start the next day with a question just like this. I usually add this example after they have had a chance to answer, and see if they want to change their minds about it:
public class Test
{
    public static void main(String[] args)
    {
        int i = 0;
		  int a = 0;
		  i = i++;
		  System.out.println("i= "+i);

		  a = i++;
        System.out.println("i= "+i);
		  System.out.println("a= "+a);
	}
}
Erik, I am learning JAVA and fit your description perfectly as far as over analyzing. However, I took your example and executed it and i did = 1 in the second step. What am I not getting here: public class ForumQ1 { public static void main(String[] args) { int i = 0; int a = 0; System.out.println("Step 1"); i = i++; System.out.println("i= "+i); System.out.println("a= "+a); System.out.println("Step 2"); a = i++; System.out.println("i= "+i); System.out.println("a= "+a); System.out.println("Step 3"); i = i++; System.out.println("i= "+i); System.out.println("a= "+a); System.out.println("Step 4"); a = i++; System.out.println("i= "+i); System.out.println("a= "+a); System.out.println("Step 5"); a = i++; System.out.println("i= "+i); System.out.println("a= "+a); System.out.println("Step 6"); i = --i; System.out.println("i= "+i); System.out.println("a= "+a); } } Results: Step 1 i= 0 a= 0 Step 2 i= 1 a= 0 Step 3 i= 1 a= 0 Step 4 i= 2 a= 1 Step 5 i= 3 a= 2 Step 6 i= 2 a= 2 Thanks Erik.
Wow. Sorry for the format. What can I do to correct? Thanks, Jerry
I couldn't edit your previous post so I'm reposting it here. By the way, you can use "pre" tags to preserve whitespace for things like this. Here's your previous post:

--------------------------------------

I am learning JAVA and fit your description perfectly as far as over analyzing. However, I took your example and executed it and i did = 1 in the second step. What am I not getting here:

public class ForumQ1 
{ 
    public static void main(String[] args) 
    { 
        int i = 0; 
        int a = 0; 

        System.out.println("Step 1");
        i = i++; 
        System.out.println("i= "+i);
        System.out.println("a= "+a); 
        System.out.println("Step 2");
        a = i++; 
        System.out.println("i= "+i);
        System.out.println("a= "+a);
        System.out.println("Step 3");
        i = i++;
        System.out.println("i= "+i);
        System.out.println("a= "+a);
        System.out.println("Step 4");
        a = i++; 
        System.out.println("i= "+i);
        System.out.println("a= "+a);
        System.out.println("Step 5");
        a = i++; 
        System.out.println("i= "+i);
        System.out.println("a= "+a);
        System.out.println("Step 6");
        i = --i;
        System.out.println("i= "+i);
        System.out.println("a= "+a);
    } 
} 

Results: 

Step 1 
i= 0 
a= 0 
Step 2 
i= 1 
a= 0 
Step 3 
i= 1 
a= 0 
Step 4 
i= 2 
a= 1 
Step 5 
i= 3 
a= 2 
Step 6 
i= 2 
a= 2 
--------------------------------------

Now that this is in place, let me look at it and see what I can come up with.
Any time I'm dealing with expressions that have multiple operands, I try to evaluate the expression operand by operand, just like the JVM does. For example, let's say you start with this:

i = i++;

I'll start by rewriting the expression with the variable values in a comment beside the expression, like this:

i = i++; // i = 0, a = 0

Next, I evaluate each operand from left to right and update my comments accordingly, like this:

i = 0; // i = 1, a = 0

Of course, I now complete the assignment and set i to 0. Going on, I run across this line, which I'll again write with the variable values in the comment:

a = i++; // a = 0, i = 0

Again, we evaluate the operands are denote variable values in the comment:

a = 0; // a = 0, i = 1

We complete the assignment, setting a to 0, which it already was, and notice that i retains its value of 1 (because we assigned the 0 to a, not to i).

Try taking that technique and applying it to the testbed you wrote and see how you fare. If you're still having trouble, let me know. In fact, a better solution would be for you to post your troubles in the JavaRanch SCJP Forums so that everyone can help.
if you have ever looked at any jvm assembly type code, you can convince yourself of how this works pretty easily... here is what the jvm is doing:
.i=0;
    iconst_0
    istore_1
.i=i++;
    iload_1
    iinc 1 1
    istore_1
the jvm is a stack machine and uses the concept of stacks instead of registers to do computation, though it does have some space allocated for local variables, they are simply for intermediate storage. most instructions compute directly off of the stack. the iconst_0 instruction means put a constant value "0" on the top of the stack. the istore_1 instruction then takes whatever is on the top of the stack and stores it in the first local variable location. then iload_1 is taking the first local variable, and putting a copy of it on the top of the stack. the iinc 1 1 instruction is a bit different, though, because it doesn't operate on the stack; rather, it operates directly on the local variable -- it is incrementing the first local variable by 1. then istore_1 pushes the top of the stack back into the first local variable. the incremented value never gets put on the top of the stack. using "i" as shorthand for the first local variable location's value and "top" for the value at the top of the stack, i'll illustrate the values after each instruction executes. so what you have is:
.i=0;
    iconst_0   ; top=0, i=(nothing)
    istore_1   ; top=(nothing), i=0;
.i=i++;
    iload_1    ; top=0, i=0
    iinc 1 1   ; top=0, i=1
    istore_1   ; top=(nothing), i=0
if you have ever worked with increment instructions then you know they all pretty much work this way. but it's a slippery slope that i still find myself sliding on every now and again!
How about THIS one, though... Explain it in terms of the JVM. int i = 0; i = i + ++i; At the end i = 1. Did you think it was going to be 2? Me to. Apparently I need to more fully understand what JVM is doing
How about THIS one, though... Explain it in terms of the JVM. int i = 0; i = i + ++i; At the end i = 1. Did you think it was going to be 2? Me to. Apparently I need to more fully understand what JVM is doing

Be sure to evaluate all operands from left to right. That means that 'i' gets evaluated prior to '++i'. Let's go through it step by step:

1. i = i + ++i; // i = 0
2. i = 0 + ++i; // i = 0
3. i = 0 + 1; // i = 1
4. i = 1; // i = 1

So, you can see that i should be 1 when the statement completes.

TrackBack to http://radio.javaranch.com/corey/addTrackBack.action?entry=1086277171000