Java:For-Each 循环和引用

2022-09-03 04:32:22

我想知道下面的循环是否创建了对象的副本,而不是给我一个引用。原因是,因为第一个示例没有分配我的数组对象,但第二个示例分配了。

MyObject objects[] = new MyObject[6];
for (MyObject o: objects) {

    o = new MyObject();
}

MyObject objects[] = new MyObject[6];
for(int i = 0; i < objects.length; i++) {

    objects[i] = new MyObject();
}

答案 1

Java的工作原理与许多其他语言略有不同。第一个示例中的内容只是对对象的引用。o

当您说 时,它会创建一个 MyObject 类型的新对象并引用该对象,而在引用之前。o = new MyObject()ooobjects[index]

也就是说,objects[index] 本身只是对内存中另一个对象的引用。因此,为了将对象[索引]设置为新的MyObject,您需要更改对象[索引]指向的位置,这只能通过使用object[index]来完成。

图片:(我糟糕的绘画技巧:D)

enter image description here

说明: 这大致就是 Java 内存管理的工作原理。不完全是,无论如何,而是粗略的。您有引用 A1 的对象。访问对象数组时,从起始参考点 (A1) 开始,然后向前移动 X 块。例如,引用索引 1 会将您带到 B1。然后B1告诉您,您正在A2处寻找该对象。A2 告诉您它有一个位于 C2 的字段。C2 是一个整数,是一种基本数据类型。搜索完成。

o 不引用 A1 或 B1,而是引用 C1 或 C2。当你说 ,它将创建一个新对象并在那里放置 o(例如,在插槽 A3 中)。它不会影响 A1 或 B1。new ...

让我知道我是否可以稍微澄清一下。


答案 2

简短的回答:是的,有类似副本的东西正在进行中。

长答案:您发布的 Java foreach 循环是语法糖

MyObject objects[] = new MyObject[6];

Iterator<MyObject> it = objects.iterator();
while (it.hasNext()) {
   MyObject o = it.next();
   // The previous three lines were from the foreach loop

   // Your code inside the foreach loop
   o = new MyObject();
}

如解糖版本所示,将引用设置为 foreach 循环中的某些内容不会更改数组的内容。