ArrayList引用赋值疑问:修改原Hashtable为何致列表元素为空?
问题解析与解决方案
嘿,这个问题的核心其实是Java里基本类型和引用类型的赋值机制差异,我给你一步步拆解清楚:
为什么基本类型的表现符合预期?
你举的int例子里,int val2 = val1;其实是把val1的数值本身复制了一份给val2。这时候val1和val2是内存里两个独立的存储单元,修改val1的值完全不会影响val2,因为它们各自持有独立的数值。
为什么Hashtable的情况会“出问题”?
Hashtable属于引用类型,和基本类型的赋值逻辑完全不同:
- 当你执行
a_j1.set(2, h_gain);时,ArrayList里存储的并不是整个Hashtable对象,而是指向这个对象在内存中位置的引用地址。 - 之后
h_tmp2 = (Hashtable<String, Integer>) a_j1.get(2);拿到的,也是同一个引用地址——也就是说,h_gain、h_tmp2和ArrayList索引2位置的元素,全都指向内存里同一个Hashtable实例。 - 所以当你调用
h_gain.clear()时,你是直接清空了内存里的那个Hashtable对象,不管通过哪个引用去访问它,看到的都会是空的结果。
怎么解决这个问题?
如果你希望ArrayList里的元素不受h_gain.clear()的影响,你需要把h_gain的副本存入ArrayList,而不是直接存原对象的引用。可以用Hashtable的拷贝构造方法来创建副本:
// 存入ArrayList的是h_gain的副本,而非原引用 a_j1.set(2, new Hashtable<>(h_gain));
这样一来,ArrayList里的元素是一个全新的Hashtable对象,和h_gain各自独立。之后再清空h_gain,就不会影响到列表里的元素了。
总结一下关键区别
- 基本类型(int、char、double等):赋值时是值拷贝,变量持有独立的值,修改互不影响。
- 引用类型(Hashtable、ArrayList、自定义类等):赋值时是引用拷贝,多个变量指向同一个内存对象,修改对象内容会通过所有引用体现。
内容的提问来源于stack exchange,提问作者Gilles
相关产品推荐
相关产品推荐

