我已经在任何地方读过Java,它在数组中存储了Object引用。甚至我自己也证明了这一点 但后来我改变了对象的状态,意味着我改变了属性的值并保存在数组中,我可以检索同一对象的多个状态。如果Array仅保存引用,那么引用如何保存状态。 例如:
class Test{
String id;
}
Test[] testArr = new Test[2];
test = new Test();
test.id = "ABC"
testArr.add(test)
test.id = "XYZ"
testArr.add(test)
现在如果我们只存储引用,那么第二次赋值将覆盖测试对象的id值,并且数组中的两个条目都具有相同的id值,但事实并非如此,我们可以检索id值ABC和XYZ。我很迷惑!
答案 0 :(得分:0)
回答你的问题。是。所有变量都只是对对象位置的引用,而不仅仅是ArrayList。编写MyObject obj = new MyObject();
会创建一个新对象,但变量obj
只是对该对象在Heap(aka内存)中的位置的引用。
ArrayList(不查看其实际实现)只是将每个对象的位置的引用存储为ArrayList的索引而不是唯一的变量。
更详细一点:您需要了解创建对象的每个部分的作用。试着以这种方式想象它:
每个对象都位于一个占用其所有字段使用的字节数的内存地址中。让我们假设我们有一个名为MyObject的对象占用100个字节。当我们使用new
关键字创建一个Object(即。new MyObject()
)时,它存储在堆中的一个内存位置(这是为程序留出的内存区域,用作动态内存分配) )。让我们说当创建这个对象时,它会占用内存空间1000(最多1100,因为它使用100个字节的内存)。所以:
| 为MyObject | < - 这是存储空间的可视化
1000
当我们写MyObject obj
时,它会在堆栈中留出内存(用于静态内存分配),这将保存对象的位置。因此,它可以保留对象在其自己位置的位置的引用,我们将假装标记为4
| ______ | < - 空记忆位置,因为它尚未分配。
4
当我们将2条指令放在一起并写入MyObject obj = new MyObject()
时,它会将对象的地址放入变量的内存位置,因此我们最终得到:
| 为MyObject | < - 实际对象的位置
1000
| 1000 | < - 引用对象位置的变量的位置
4
答案 1 :(得分:0)
看看这段代码:
class Test {
String id = "A";
}
public class Main {
public static void main(String[] args) {
ArrayList<Test> list = new ArrayList<Test>();
// Adding some Test Object to the list.
Test foo = new Test();
list.add(foo);
System.out.println("Value of foo id: " + foo.id);
// Retrieving the Object from the list & changing the value
Test bar = list.get(0);
bar.id = "B";
System.out.println("Value of foo id: " + foo.id);
}
}
输出:
Value of foo id: A
Value of foo id: B
正如您所见,arraylist只保留引用。如果从列表中检索对象并更改其中的内容,则原始对象也将更改