1

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.

saroff
  • 688
  • 9
  • 20

1 Answers1

6

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.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • Not sure how does that answer *"why javac copy ref to array into another local var"* – Jean-François Savard Apr 10 '15 at 00:19
  • @Jean-FrançoisSavard it's the ref to `indexes` that is being copied (into another hidden local variable, which I've called `hidden_array_ref`) – user253751 Apr 10 '15 at 00:20
  • Oh, that's what I missed. – Jean-François Savard Apr 10 '15 at 00:21
  • Wow, ty. I was thought that changing array inside loop it's programmer problem or not allowed at all. I try it now with normal for loop like this: `int[] array = new int[10]; for (int i = 0; i < array.length; i++) {}` And no copies was generated. So we allowed to do some unpredictable manipulations with array in this loop? – saroff Apr 10 '15 at 00:35
  • 2
    @saroff: the definition is simply that if you use `for(var : expression)`, the `expression` is evaluated only once. It may be another local variable like in you case, but think of `for(byte b: Files.readAllBytes(pathToMyFile))`; in this case the file is read only once at the beginning of the loop, not in every iteration… – Holger Apr 10 '15 at 10:54