java中的对象。当它们不再分配给变量后,会发生什么?

java中的对象。当它们不再分配给变量后,会发生什么?,java,hashmap,Java,Hashmap,当我遇到一个自己无法解决或在网上找不到的问题时,我一直在使用HashMaps HashMap<String,HashMap<String,String>> m= new HashMap<>(); HashMap<String,String> t = new HashMap<>(); t.put("test1","1"); m.put("h1",t); t = new HashMap<>(); t.put("test2,"

当我遇到一个自己无法解决或在网上找不到的问题时,我一直在使用HashMaps

HashMap<String,HashMap<String,String>> m= new HashMap<>();
HashMap<String,String> t = new HashMap<>();

t.put("test1","1");
m.put("h1",t);

t = new HashMap<>();
t.put("test2,"2");
m.put("h2",t);

System.out.println(m);
HashMap m=newhashmap();
HashMap t=新的HashMap();
t、 出售(“测试1”、“1”);
m、 put(“h1”,t);
t=新HashMap();
t、 put(“test2,2”);
m、 put(“h2”,t);
系统输出打印项次(m);
这给了我
{h1={test1=1},h2={test2=2}}

因此,大的HashMap包含了两个HashMap的数据,所以问题是它是简单地复制了较小的HashMap的数据,还是同时复制了这两个HashMap的数据“HashMaps保存在JVM内存中,HashMap
m
只是将我链接到它们?

无论何时将
t
放入
m
,都不会复制数据。而是放置对子贴图的引用

t
添加到
m
两次。但是,每次
t
都指向不同的对象。因此,您将在
m
中得到两个独立的子贴图

将此与以下示例进行对比:

      t.put("subkey","old");
      m.put("h1",t);
      m.put("h2",t);
      t.put("subkey", "new");
      System.out.println(m);
这是打印出来的

{h1={subkey=new}, h2={subkey=new}}

这里,
t
m
的两个键指向同一个子地图。当您更改一个时,它们都会更改。

无论何时将
t
放入
m
,都不会复制数据。而是放置对子贴图的引用

t
添加到
m
两次。但是,每次
t
都指向不同的对象。因此,您将在
m
中得到两个独立的子贴图

将此与以下示例进行对比:

      t.put("subkey","old");
      m.put("h1",t);
      m.put("h2",t);
      t.put("subkey", "new");
      System.out.println(m);
这是打印出来的

{h1={subkey=new}, h2={subkey=new}}

这里,
t
m
的两个键指向同一个子地图。当你改变一个对象时,它们都会改变。

Map
包含对象的引用。它内部包含
Entry
类的数组bucket,该类保存键、值对象引用


HashMap
m将包含第一个创建的HashMap相对于h1的对象引用和第二个HashMap相对于h2的引用。

Map
包含对象的引用。它内部包含
Entry
类的数组bucket,该类保存键、值对象引用


HashMap
m将包含第一个创建的HashMap对h1的对象引用和第二个HashMap对h2的引用。

Java中的所有内容都是指针或引用,因此对象保存在内存中,HashMap存储引用,而不是复制实际数据


大哈希映射包含对小哈希映射的引用,因此垃圾收集器不会释放内存。

Java中的所有内容都是指针或引用,因此对象保存在内存中,哈希映射存储引用,而不是复制实际数据


大哈希映射包含对较小哈希映射的引用,因此垃圾收集器不会释放内存。

您的大哈希映射包含对这两个哈希映射的引用。您所做的是更改
HashMap
t
所指向的内容

作为一个更直观的例子,让我们说

t = 0x00000001
当您将
t
放入
m
时,
m
现在看起来像

m = {0x00000001}
此时,
t
m
都引用了相同的
HashMap
,这意味着对其中一个的任何更改都将出现在另一个中。现在,当您转到
t=newhashmap()
时,实际上是在重新分配
t
指向的引用

t = 0x00000002
但是
m
看起来仍然像
{0x00000001}
,所以您没有丢失第一个引用。当你第二次将
t
放入
m
时,它们看起来像

t = 0x00000002
m = {0x00000001, 0x00000002}

所以最后,
m
仍然包含对两个
HashMaps

的引用。您的大
HashMap
包含对这两个
HashMaps
的引用。您所做的是更改
HashMap
t
所指向的内容

作为一个更直观的例子,让我们说

t = 0x00000001
当您将
t
放入
m
时,
m
现在看起来像

m = {0x00000001}
此时,
t
m
都引用了相同的
HashMap
,这意味着对其中一个的任何更改都将出现在另一个中。现在,当您转到
t=newhashmap()
时,实际上是在重新分配
t
指向的引用

t = 0x00000002
但是
m
看起来仍然像
{0x00000001}
,所以您没有丢失第一个引用。当你第二次将
t
放入
m
时,它们看起来像

t = 0x00000002
m = {0x00000001, 0x00000002}

因此,最后,
m
仍然包含对两个
哈希映射的引用

这两个哈希映射都将保留在内存中。您可以使用h1和h2键通过hashmap m引用它们。数据不会从hashmaps复制,但对象的引用将更改为hashmap键(即h1和h2)。

两个hashmap都将保留在内存中。您可以使用h1和h2键通过hashmap m引用它们。数据不会从hashmaps复制,但对象的引用会更改为hashmap键(即h1和h2)。

#2是答案。数据没有被复制,m只是指向哈希映射的两个实例。t没有指向前面的hashmap实例这一事实并不意味着如果其他人指向它(m),然后再阅读一些,它就会消失。数据没有被复制,m只是指向哈希映射的两个实例。t没有指向前面的hashmap实例这一事实并不意味着如果其他人指向它(m),然后再阅读一些内容,它就会消失。