Java Incremental operator query (++i and i++)

misguided picture misguided · Jun 26, 2014 · Viewed 8k times · Source

I have the following code:

public class Book {
    private static int sample1(int i) {
        return i++;
    }
    private static int sample2(int j) {
        return ++j;
    }

    public static void main(String[] arguments){ 
        int i = 0;
        int j = 0;
        System.out.println(sample1(i++)); //0
        System.out.println(sample1(++i)); //1
        System.out.println(sample2(j++));//1
        System.out.println(sample2(++j));//2
        System.out.println(i);//2
        System.out.println(j);//2
    }
}

My expected output is in comments. The actual output is below:

0
2
1
3
2
2

I'm getting confused with the function calls and incemental operator. Can someone kindly explain the actual result?

Answer

ruakh picture ruakh · Jun 26, 2014

Since sample1 and sample2 are just modifying their own local variables i and j (not those of the calling method), it's clearer if we rewrite them without those modifications:

private static int sample1(int i) {
    return i;   // was 'i++', which evaluates to the old i
}
private static int sample2(int j) {
    return j + 1;   // was '++j', which evaluates to j after incrementing
}

At which point it's straightforward to just substitute them in place — sample1(...) becomes ..., and sample2(...) becomes ... + 1:

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

We can make this a bit clearer by separating the incrementations into their own commands. i++ evaluates to the original value of i, so it's like incrementing i after running the surrounding command; ++i, by contrast, is like incrementing i before running the surrounding command. So we get:

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

. . . at which point it should be straightforward to trace through and see what it will output.

Does that all make sense?