Java中的“浅拷贝与深拷贝”

今天在使用Arrays的时候,偶然发现了一个与前面Python的一篇文章类似的问题,也就是浅拷贝与深拷贝的问题,链接如下:

http://www.cnblogs.com/sumory/archive/2011/01/18/1938551.html 

 

String[] strs = { "1""2""3""4""5""6""7""8""9""10" };
        List
<String> list3 = Arrays.asList(strs);

        Collections.shuffle(list3);//random
        print(list3);

        
for (String u : strs)
        {
            System.out.println(u);

System.out.println(list3.get(0).hashCode()+" "+strs[0].hashCode()); //结果相同

 

上面的结果是list3顺序改变,数组顺序同list3一样,也发生改变。我们猜想,Arrays.asList只不过把list3指向了数组,并没有产生新数据,list3所做的更改会反映到strs上。实验验证以上想法:

 

String[] strs = { "1""2""3""4""5""6""7""8""9""10" };
        List
<String> list3 = Arrays.asList(strs);
        print(list3);
        Collections.shuffle(list3);
        print(list3);

        
for (String u : strs)
        {
            System.out.println(u);
        }
        
        System.out.println(list3.get(
0).hashCode()+" "+strs[0].hashCode());//the same
        
        list3.set(
0,"i am changed");
        
        print(list3);

        
for (String u : strs)
        {
            System.out.println(u);


打印显示,跟我们想的一样,strs和list3的第一个元素都变为了"i am changed"。 

综合上述,可以看出, Arrays.asList 使用的是浅拷贝,同时list3已经不能在调用add方法了(请看jdk源码注释),这样请尤其注意不要随便使用这个方法,因为新list的操作会反映到原数据上。

 

我们再来看一下"深拷贝"的情况: 

将List<String> list3 = Arrays.asList(strs);换为List<String> list2 = new ArrayList<String>(Arrays.asList(strs)); ,会发现结果就完全不同了,list3的操作不再会作用到strs上,同时list3也可使用一般ArrayList跟size相关的操作了,这是因为new了新对象,具体就不介绍了,大家应该一看就懂。

 

ps:其实,这种api如果不看源码的话(尤其是注释),很容易因为稀里糊涂地采用而导致出错。大家还有什么这种类似的问题请发上来讨论,共同进步! 

 

posted @ 2011-04-16 19:07  sumory  阅读(500)  评论(0编辑  收藏  举报