为什么javac有时会创建不必要的变量副本?

sar*_*off 1 java bytecode javac

我的代码看起来像这样:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

字典代码:

ASTORE 3 //"indexes" array
...
ALOAD 3
ASTORE 8
ALOAD 8
ARRAYLENGTH
...
Run Code Online (Sandbox Code Playgroud)

我不确定为什么javac复制引用数组到另一个本地var.

use*_*751 6

for-each循环转换为如下所示:

{
    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');
    }
}
Run Code Online (Sandbox Code Playgroud)

特别注意int[] hidden_array_ref = indexes;.那是你要问的副本.

编译器这样做,所以如果你写这样的东西:

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

赋值indexes不会影响循环.

  • @saroff:定义很简单,如果你使用`for(var:expression)`,`expression`只被评估一次.它可能是另一个局部变量,就像在你的情况下,但想到`for(byte b:Files.readAllBytes(pathToMyFile))`; 在这种情况下,文件在循环开始时只读取一次,而不是在每次迭代中读取... (2认同)