1.下面代码输出结果为:chen
// deep cloning Collection in Java List<Employee> list1= new ArrayList<Employee>(); list1.add(new Employee("Joe", "Manager")); list1.add(new Employee("Tim", "Developer")); list1.add(new Employee("Frank", "Developer")); // creating copy of Collection using copy constructor List<Employee> list2 = new ArrayList<Employee>(); list2.addAll(list1); list1.get(0).setName("chen"); System.out.println(list2.get(0).getName());
2.下面代码输入为2
List<Object> aList = new ArrayList<Object>();
List<Object> bList = new ArrayList<Object>();
aList.add("1");
aList.add("2");
bList.addAll(aList);
aList.set(1, 22);
aList.clear();
aList = null;
System.out.println(bList.get(1));
对于1的问题,因为list.addAll 不是深度copy,所以虽然list2是重新new出来的对象,
但是list1、list2指向的底层都是之前创建的Employee,所以list1改变Employee的时候
导致了list2中Employee对应发生了变化,这么理解对吗?
对应2,为啥输出的结果是2呢?请大神指教。。
因为add的是String对象,在这里你可以把String当作值类型看待。(String有两大特性:只读性和唯一性)
你alist clear掉了只是剪断了它对堆上数据的关系,但blist这种关系还维持着在啊。
1中集合中存储的为对象(引用类型)。list2.addAll(list1);使得list1和list2对Employee对象的引用路径一致,list1.get(0).setName("chen");只是修改了Employee对象,而没有修改list2对对象的引用,故最后输出:chen
这是一个java常识问题,一句话解释就是String是一个特殊的Object对象。
详细说呢:String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不 可变的。
举例说呢:
String a = new String("xxx");
String b = a;
b="yyy";
这时候,a还是xxx,而不会因为a、b都指向new String("xxx"||)这个对象,改变b就改变a。
b="yyy"执行时,将一个新的String常量"yyy"给了b,而“xxx”还在常量池里,由a来指向。
你这个问题,就是这个原因的一种现象,把aList清除,并不会影响bList,因为bList的对象在String常量池里,并没有因为aList.clear();执行而被释放。