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();
}
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();
}
Java的工作方式与许多其他语言略有不同。在第一个示例中,o
只是指向对象的引用。
当你说o = new MyObject()
时,它会创建一个类型为MyObject的新对象,并将o
引用到该对象,而之前o
引用了objects[index]
。
也就是说,objects[index]
本身只是指向内存中另一个对象的引用。因此,要将objects[index]
设置为一个新的MyObject,则需要更改objects[index]
指向的位置,这只能通过使用objects[index]
来完成。
图像:(我的绘画技巧很糟糕:D)
说明: 这大致是Java内存管理的工作方式。绝非完全如此,但大致如此。您有对象(Object),它们引用A1。当您访问对象数组时,从开始的引用点(A1)开始,向前移动X个块。例如,引用索引1会将您带到B1。 B1然后告诉您正在寻找位于A2上的对象。 A2告诉您它具有位于C2上的字段。 C2是一个整数,是基本数据类型。搜索完成。
o
不引用A1或B1,而是引用C1或C2。当您说new ...
时,它会创建一个新对象并将其放置在o
中(例如,在槽A3中)。它不会影响A1或B1。
如果需要更多解释,请告诉我。
=
会重新引用它们。你不能在引用的地方创建一个新变量。但是,你可以更改这个变量。如果 o
已经初始化并且 o.x
是一个字段,你可以更改 o.x
指向的位置,从而重新分配 o.x
。 - Ryan Amos简短回答:是的,确实会发生类似复制的情况。
长回答:你发布的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循环内将引用设置为某个内容不会改变数组的内容。
MyObject objects[] = new MyObject[6];
for(MyObject o: objects) {
// Construct a new object of type MyObject and assign a reference to it into
// the iteration variable o. This has no lasting effect, because the foreach
// loop will automatically assign the next value into the iteration variable
// in the the next iteration.
o = new MyObject();
}
第二个例子:
MyObject objects[] = new MyObject[6];
for(int i = 0; i < objects.length; i++) {
// Construct a new object of type MyObject and store a reference to it into the
// i-th slot in array objects[]:
objects[i] = new MyObject();
}
foreach
循环迭代集合中的元素而未分配数组对象。当您进入该foreach
循环时,您的集合中没有任何元素,它只是一个初始化为大小6的空数组,因此不会向您的数组添加对象。另外需要注意的是,即使数组中有元素,foreach
循环也不会覆盖它们。o = new MyObject();
MyObject
实例分配给o
,但是o
本身并不是数组objects
的一部分,它只是一个临时容器,用于迭代数组的元素,但在这种情况下,没有任何元素。MyObject
的元素。 - Hunter McMillen只有在明确声明要克隆对象时(并且该对象明确实现了克隆功能),才会“复制”对象。
您似乎混淆了引用和名称。
在第一个示例中,在foreach内部,本地变量o
引用存储在objects
中的某个对象的内存区域。当您执行o = new MyObject()
时,会在另一个内存区域初始化一个新的MyObject,然后将o
引用重写为指向此新的内存区域。
在第二个示例中,通过编写objects[i] = new MyObject()
,您正在表示应重写objects[i]
引用,而不是某个本地o
变量。
我想首先提到的是,非零长度的数组总是可变的。而在foreach循环中
for(MyObject o in objects)
它的作用是在每次迭代中按照以下方式工作。
o = objects[0] // first iteration
o = objects[1] // 2nd iteration
ObjeMyObject objects[] = new MyObject[6];
MyObject o = Object[0];
0 = new MyObject();
但是你的原始对象[0]仍然指向一个空对象。
O = Object[0]
O = Object[1]
O = Object[2]
O = Object[3]
O = Object[4]
O = Object[5]
我们不需要关注计数器的增加,这就是 for each 循环的优美之处。
for-each
循环。 - RanRag