Search code examples
javajavacbytecode

Why javac sometimes creates unnecessary copies of variables?


I have code looks like this:

boolean[] array = new boolean[200];
int[] indexes = {10, 42, 62, 74};
while(true) {
    //some code here
    StringBuilder sb = new StringBuilder();
    for (int j : indexes) {
        sb.append(array[j] ? '1' : '0');
    }
}

Bytecode for this:

ASTORE 3 //"indexes" array
...
ALOAD 3
ASTORE 8
ALOAD 8
ARRAYLENGTH
...

I am not sure about why javac copy ref to array into another local var.


Solution

  • The for-each loop is converted into something like this:

    {
        int[] hidden_array_ref = indexes;
        int hidden_length = hidden_array_ref.length;
        for(int hidden_counter = 0; hidden_counter < hidden_length; hidden_counter++) {
            int j = hidden_array_ref[hidden_counter];
            sb.append(array[j] ? '1' : '0');
        }
    }
    

    In particular, notice int[] hidden_array_ref = indexes;. That's the copy you are asking about.

    The compiler does it this way so that if you write something like:

    for(int j : indexes) {
        indexes = new int[0];
        sb.append(array[j] ? '1' : '0');
    }
    

    the assignment to indexes doesn't affect the loop.