Java增强型for循环 - 编辑原始数组值

5

我想详细了解Java中的增强型for循环是如何工作的(假设我已经了解了该循环的基本用法和一般工作原理)。

给定以下代码:

String[] a = {"dog", "cat", "turtle"};

for (String s : a) {
  out.println("String: " + s);
  s = in.readLine("New String? ");
}

它实际上并没有修改原始列表'a'。

为什么?内存管理是如何工作的?'s'不是对'a[i]'相同的内存单元的引用吗?

我在Oracle文档中阅读到增强型for循环无法用于从原始数组中删除元素,这是有道理的。那么修改值是否也是如此呢?

提前致谢。


3
字符串是不可变的。 - Shashi
s是一个变量,其中包含对容器元素的引用。 - Roman C
5个回答

11

's'不是指向'a[i]'的同一内存单元吗?

最初确实如此。但随后,in.readLine会生成对新字符串对象的引用,然后您使用该引用来覆盖s。但只有s被覆盖了,底层字符串和数组中的引用未被更改。


1
@Oliver,你的意思是当我们执行s = new String("X")时,引用s开始指向其他字符串对象而不是a[i]吗? - Abhinav

5

s 是一个指向 String 实例的本地变量。它与 a[i] 没有关联,它们最初只是具有相同的值。


3

您只能编写文本

for (int i = 0; i < a.length; i++) {
  out.println("String: " + a[i]);
  a[i] = in.readLine("New String? ");
}

您不能使用for-each循环来修改原始集合或数组。


你澄清了最后一个仍然模糊的点。非常感谢! - jnardiello
1
如果您想要删除(remove())或更改列表的条目,您必须显式地使用迭代器(Iterator)。 - Peter Lawrey

1

像将 s 视为对象的地址一样思考。这里的问题在于,在使用 for 循环时,s 指向数组的某个特定值。当你在循环内重新分配 s 时,s 只是指向另一个值,但数组的原始值并未被修改,因为你只是改变了 s 指向的地址。

String[] a = {"dog", "cat", "turtle"};

for (String s : a) {
  //s --> "dog"
  out.println("String: " + s);
  s = in.readLine("New String? ");
  //s --> the new string the user inputs
}

1
非常感谢您详细的回答。我缺少的是readLine返回一个新地址的事实。 - jnardiello
如果您的问题得到了解答,请随意点赞并接受答案 ;) - Averroes

1

对于每次迭代,字符串s最初引用String a[]中相应的字符串对象。但它随后被引用另一个由in.readLine()返回的字符串对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接