符合GC条件的Java For Each循环内创建的字符串

use*_*412 4 java arrays

来自不同的语言,这似乎让我困惑.

String [] names = new String[]{"A","B","C"};
for (String n : names){
    n = new String(n+"hello");
}
System.out.println(Arrays.toString(names)); // [A, B, C]
Run Code Online (Sandbox Code Playgroud)

names 仍然有原始值[A,B,C],我相信这是由于不变性,但这是否意味着我在迭代数组时创建了三个垃圾收集字符串?

然而这段代码确实修改了数组?

Car [] cars = { new Car("red"), new Car("green") };
    for(int i=0; i<cars.length; i++){
        Car c = cars[i];
        c.color ="black";
    }

    for(int i=0; i<cars.length; i++){
        Car c = cars[i];
        System.out.println(c.color);    //prints black, black
    }
Run Code Online (Sandbox Code Playgroud)

Psh*_*emo 6

这段代码

for (String n : names){
    n = new String(n+"hello");
}
Run Code Online (Sandbox Code Playgroud)

和...一样

for (int i = 0; i<names.length; i++){
    String n = names[i];
    n = new String(n+"hello");
}
Run Code Online (Sandbox Code Playgroud)

所以你看到分配n新值不能影响数组.是的,在每次迭代结束时,通过创建的字符串new String(n+"hello");将有资格进行垃圾回收.

但是因为n默认情况下会保存相同的对象,因为names[i]您可以使用它来更改所保持对象的状态.例如,如果您的数组是数组Persons,通过n您将能够更改age存储的Person之类的属性

n.setAge(42);
Run Code Online (Sandbox Code Playgroud)

您还可以为其分配新值n,

n = new Person("Jack", 40);
Run Code Online (Sandbox Code Playgroud)

但这并不意味着您要将新值分配给names[i]因为n并且names[i]是不同的变量.

也许这会对你有所帮助

n = names[i]情况看起来像这样:

names[i] ----+       +--------+
             |       | Person |
             +------>+--------+
             |       | name   | //Adam 
       n ----+       | age    | //30
                     +--------+
Run Code Online (Sandbox Code Playgroud)

因此两个变量(引用)都包含相同的实例,这允许您从两个变量中操作它(如果您更改nameage通过n您也将通过names[i]因为它们持有相同的对象也看到此更改)

但如果你这样做

n = new Person("Jack", 42);
Run Code Online (Sandbox Code Playgroud)

你只是分配新对象n,而不是names[i],所以情况会如此

                     +--------+
                     | Person |
names[i] ----------->+--------+
                     | name   | //Adam 
                     | age    | //30
                     +--------+

                     +--------+
                     | Person |
       n ----------->+--------+
                     | name   | //Jack
                     | age    | //42
                     +--------+
Run Code Online (Sandbox Code Playgroud)

这意味着array(names[i])不会改变.

简而言之,n您不能将new元素放到数组中,但您可以更改现有元素的状态.