今天工作遇到一个问题,我在程序里面,启动会给一个Map<Stirng,List<String>> map对象赋值,key和value都有值,但是启动过了五分钟,发现一些key的值变为了空值,我检查了所有代码,中只有一个map.put的方法,我本来以为map存在和list一样的内存机制,就写了下测试代码:
public class test {
public static void main(String[] args) {
Map<String,List<String>> map = new HashMap<String,List<String>>();
List<String> list = new ArrayList<String>();
list.add("111");
map.put("test", list);
System.out.println("map==1==="+map);
list = new ArrayList<String>();
System.out.println("list==2==="+list);
System.out.println("map==3==="+map);
list = null;
System.out.println("list==4==="+list);
System.out.println("map==5==="+map);
List<String> list_1 = map.get("test");
System.out.println("list==6==="+list_1);
list_1 = new ArrayList<String>();
System.out.println("list==7==="+list_1);
System.out.println("map==8==="+map);
}
}
输出的结果如下:
map==1==={test=[111]}
list==2===[]
map==3==={test=[111]}
list==4===null
map==5==={test=[111]}
list==6===[111]
list==7===[]
map==8==={test=[111]}
并没有通过重新赋值的方式将map的值修改了,
后来找来同事一起检查代码,发现了一个特殊的地方:list_1.clear(),难道是他造成的影响?
再次测试:
public class test {
public static void main(String[] args) {
Map<String,List<String>> map = new HashMap<String,List<String>>();
List<String> list = new ArrayList<String>();
list.add("111");
map.put("test", list);
System.out.println("map==1==="+map);
list = new ArrayList<String>();
System.out.println("list==2==="+list);
System.out.println("map==3==="+map);
list = null;
System.out.println("list==4==="+list);
System.out.println("map==5==="+map);
List<String> list_1 = map.get("test");
System.out.println("list==6==="+list_1);
// list_1 = new ArrayList<String>();
// System.out.println("list==7==="+list_1);
// System.out.println("map==8==="+map);
list_1.clear();
System.out.println("list==9==="+list_1);
System.out.println("map==10==="+map);
}
}
输出的结果如下:
map==1==={test=[111]}
list==2===[]
map==3==={test=[111]}
list==4===null
map==5==={test=[111]}
list==6===[111]
list==9===[]
map==10==={test=[]}
果然是clear方法搞的鬼,map的内存机制还是有特殊的地方。
个人理解:当map.get("test")复制给list_1,其实是给了list_1一个纸箱map的test的key的索引,当你list_1.clear()的时候,直接将索引对应的对象给清空了。但是使用list_1 = new ArrayList<String>()的时候,应该是重新给list_1在内存中分配了一个空间。
以上是个人见解,对于内存的机制不够了解,作为一个开发人员太不称职了,我决定好好的研究下java的内存机制,等搞明白了,再继续补充原理。。。。。