Map 存储引用变量的副本还是对象的副本?

Does Map store copy of the reference variable or copy of the object?

我有这个小代码片段,想知道 java.Util.Map 存储引用变量副本或对象副本的实现。

public static void main(String[] args) {
    List<Integer> obj = Arrays.asList(1,2,3);
    Map<Integer, List<Integer>> a = new HashMap<>();
    a.put(0, obj);
    a.get(0).forEach(System.out::print);
    obj = Arrays.asList(4,5,6);
    System.out.println();
    a.get(0).forEach(System.out::print);
}

输出

123
123

我觉得这个问题的答案一定已经存在(好吧,它可能已经存在但我找不到),我阅读了以下答案但对我的问题了解不多

Does Java return by reference or by value

这个答案说,如果 Integer 是可变的,但 ArrayList 是可变的 (),那么为什么它没有发生呢?

第一个:Arrays::asList 创建一个固定大小的列表。
第二行

obj = Arrays.asList(4,5,6);

创建一个新列表对象

为了检验您的假设,我们需要创建一个可修改列表,将其添加到地图,然后修改列表:

public static void main(String[] args) {
  List<Integer> obj = new ArrayList<>(Arrays.asList(1,2,3));
  Map<Integer, List<Integer>> a = new HashMap<>();
  a.put(0, obj);
  a.get(0).forEach(System.out::print);
  obj.clear();
  obj.add(4);
  obj.add(5);
  obj.add(6);
  System.out.println();
  a.get(0).forEach(System.out::print);
}

Ideone demo

我们看到以下输出:

123
456

这证实地图没有复制列表,而只包含对它的引用。

我觉得这里可能有点误会。当您最初执行 List<Integer> obj = Arrays.asList(1,2,3); 时,obj 引用的对象是一个包含 1,2,3 的列表。这个列表放在地图上。

但是,当您执行 obj = Arrays.asList(4,5,6); 时,您正在将一个新对象分配给引用 obj

试试这个:

public static void main(String[] args){
        List<Integer> obj = new ArrayList<>();
        obj.add(1);
        Map<Integer, List<Integer>> a = new HashMap<>();
        a.put(0, obj);
        a.get(0).forEach(System.out::println);
        obj.add(2);
        System.out.println();
        a.get(0).forEach(System.out::println);
    }