Java: For-Each循环和引用

24 浏览
0 Comments

Java: For-Each循环和引用

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

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();
}

0
0 Comments

Java中的For-Each循环和引用

在Java中,我们经常使用For-Each循环来遍历数组或集合。然而,有时候我们可能会遇到一些问题,这篇文章将讨论一个常见的问题以及解决方法。

问题描述:

我们先来看一个例子:

MyObject objects[] = new MyObject[6]; 
for(MyObject o: objects) { 
    // 构造一个新的MyObject对象,并将引用赋值给迭代变量o。然而,这没有持久的效果,
    // 因为在下一次迭代中,foreach循环将自动将下一个值赋给迭代变量。
    o = new MyObject(); 
} 

在这个例子中,我们尝试使用For-Each循环来为数组中的每个元素创建一个新的MyObject对象,并将引用赋值给迭代变量o。然而,这样做是无效的,因为在下一次迭代中,迭代变量o将被自动赋予下一个值,而不是我们创建的新对象的引用。

解决方法:

为了解决这个问题,我们可以改用传统的For循环来遍历数组,并将新创建的对象的引用分配给数组的相应元素。例如:

MyObject objects[] = new MyObject[6]; 
for(int i = 0; i < objects.length; i++) { 
    // 构造一个新的MyObject对象,并将引用存储到数组objects[]的第i个槽中:
    objects[i] = new MyObject(); 
} 

在这个例子中,我们使用传统的For循环来遍历数组,并使用索引i来访问每个数组元素。这样,我们可以将新对象的引用分配给数组的相应元素,确保我们创建的新对象在迭代之后仍然可用。

在使用For-Each循环时,需要注意不能直接为数组或集合中的元素赋值,因为这不会持久地改变数组或集合的内容。为了解决这个问题,我们可以改用传统的For循环,并使用索引来访问和修改数组或集合的元素。

0
0 Comments

Java中的for-each循环和引用的问题起因于在foreach循环中将引用设置为其他值时,并不会改变数组的内容。解决方法是使用普通的for循环来遍历数组,并直接修改数组的内容。以下是具体内容:

短答案是:是的,确实发生了类似复制的操作。

长答案是:你在Java中使用的foreach循环实际上是语法糖,等价于下面的代码:

MyObject objects[] = new MyObject[6];
Iterator it = objects.iterator();
while (it.hasNext()) {
   MyObject o = it.next();
   // 上述三行代码对应于foreach循环
   // foreach循环内的代码
   o = new MyObject();
}

从上述代码可以看出,将引用设置为其他值并不会改变数组的内容。

因此,解决这个问题的方法是使用普通的for循环来遍历数组,并直接修改数组的内容。

0
0 Comments

Java中的ForEach循环和引用

Java与许多其他语言的工作方式略有不同。在第一个示例中,o只是对对象的引用。

当你说o = new MyObject()时,它会创建一个类型为MyObject的新对象,并将o引用到该对象,而之前o引用了objects[index]。

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

这是大致描述Java内存管理工作方式的图示。不完全准确,但可以大致理解。你有一个objects数组,引用A1。当你访问objects数组时,从开始的引用点(A1)开始,向前移动X个块。例如,引用索引1会将你带到B1。然后,B1告诉你要查找A2处的对象。A2告诉你它在C2处有一个字段。C2是一个整数,一个基本数据类型。搜索完成。

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

当然,这是有道理的。所以在第一个示例中,o有点像C++指针,因为它本身是一个变量,因此它的值是另一个变量的地址。因此,当分配任何东西给它时,设置的是变量本身,而不是它指向的内容。

确切地说,与C++不同,Java在指针控制方面没有太多的功能。变量引用内存中的位置,而"="重新引用它们。你不能在你引用的位置创建一个新的变量。但是,你可以改变这个变量。如果o已经被初始化,o.x是一个字段,你可以改变o.x的指向,从而重新分配o.x。

希望这能帮助你理解。

0