【问题标题】:Does ArrayList Actually Stores references onlyArrayList 实际上只存储引用吗
【发布时间】:2016-03-09 03:58:54
【问题描述】:

Java 将对象引用存储在数组中的所有地方我都读过它。甚至我自己也证明了这一点。 但是后来我改变了对象的状态,这意味着我改变了属性的值并保存在数组中,我可以检索同一个对象的多个状态。如果 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。我很迷惑!

【问题讨论】:

  • 这甚至无法编译...您在普通数组上调用add。是的,如果以正确的方式完成此操作,您将在数组中两次拥有相同的Test 实例,id 的值为XYZ。此外,没有任何数组不仅存储引用,它们还存储引用的值,或者对于基元,存储值本身。 refer to Is Java “pass-by-reference” or “pass-by-value”?

标签: java arrays object memory-management reference


【解决方案1】:

看看这段代码:

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 仅包含引用。如果您从列表中检索对象并更改其中的某些内容,则原始对象也会被更改

【讨论】:

    【解决方案2】:

    回答你的问题。是的。所有变量都只是对对象位置的引用,而不仅仅是 ArrayList。写入MyObject obj = new MyObject(); 会创建一个新对象,但变量obj 只是对该对象在堆(也称为内存)中位置的引用。

    ArrayList(不看它的实际实现)只是将每个对对象位置的引用存储为 ArrayList 的索引而不是唯一变量。

    更详细一点:您需要了解创建对象的每个部分的作用。试着用这种方式想象它:

    每个对象都位于一个内存地址中,该地址占用了其所有字段使用的字节数。假设我们有一个名为 MyObject 的对象,它占用 100 个字节。当我们使用new 关键字(即new MyObject())创建对象时,它存储在堆中的内存位置(这是为您的程序留出的内存区域,用作动态内存分配)。让我们说,当这个对象被创建时,它占用了 1000 个内存空间(最多 1100 个,因为它使用了 100 个字节的内存)。所以:

    |我的对象| 1000

    当我们编写MyObject obj 时,它会在堆栈中留出内存(用于静态内存分配),这将保存对象的位置。所以它可能会在它自己的位置保存对对象位置的引用,我们将假装它被标记为 4

    |______| 4

    当我们把 2 条指令放在一起写 MyObject obj = new MyObject() 时,它会将对象的地址放入变量的内存位置,所以我们最终得到:

    |我的对象| 1000

    |1000| 4

    【讨论】:

      猜你喜欢
      • 2022-11-15
      • 1970-01-01
      • 2011-12-07
      • 2023-03-13
      • 2011-01-13
      • 2019-01-02
      • 2011-03-15
      • 1970-01-01
      相关资源
      最近更新 更多