java - 在符合 GC 条件的 Java For Each 循环中创建的字符串

标签 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]

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
    }

最佳答案

这段代码

for (String n : names){
    n = new String(n+"hello");
}

相同
for (int i = 0; i<names.length; i++){
    String n = names[i];
    n = new String(n+"hello");
}

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

但是自n默认情况下拥有与 names[i] 相同的对象您可以使用它来更改持有对象的状态。例如,如果您的数组是 Persons 的数组, 通过 n您将能够更改属性,例如 age存储的人

n.setAge(42);

您还可以为 n 分配新值,

n = new Person("Jack", 40);

但这并不意味着您要为 names[i] 分配新值因为nnames[i]是不同的变量。

也许这对你有一点帮助

n = names[i]情况是这样的:

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

因此两个变量(引用)都持有相同的实例,这允许您从两个变量对其进行操作(如果您通过 name 更改 agen,您也将通过 names[i] 看到此更改。因为他们持有相同的对象)

但如果你这样做

n = new Person("Jack", 42);

您仅将新对象分配给 n ,而不是names[i] , 所以情况会是

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

                     +--------+
                     | Person |
       n ----------->+--------+
                     | name   | //Jack
                     | age    | //42
                     +--------+

这意味着数组 ( names[i]) 没有改变。

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

关于java - 在符合 GC 条件的 Java For Each 循环中创建的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28184097/

相关文章:

java - Spring Boot 应用程序中的 Mockito 模拟和 spy

regex - 在 Perl 中,是否存在 ${foo[bar]} 可能是语法上有效的代码的任何场景?

java - 如何在 ModelMapper 的 AbstractConverter.convert() 方法中到达目标对象

java - 如何修复 Android : could not find class java. awt.datatransfer.DataFlavor 上的 Spongy CaSTLe 错误

java - 选择选项卡时触发 JTabbedPane 事件

arrays - 使用未解析的标识符 'WeekOne'

java - 在宽范围的整数数组中查找第一个重复元素?

php - 将mysql结果放在一个数组中

php - 如何在php中将数据推送到数组中

java - 在 RabbitMQ 中组接收消息,最好使用 Spring AMQP?