探讨java 值引用和对象引用在addAll方法下的不同

 

在优化代码的时候发现一个问题  ListA使用addAll 方法得到了ListB的值  但是我在修改ListA集合中某一个元素的值时 发现原集合ListB的值也跟着改变了 ; 

探讨java 值引用和对象引用在addAll方法下的不同_第1张图片

该图片当时搞得我很懵,我刚开始只知道 ListA=ListB 的时候 改变ListA 的值 ListB的值也会跟着改 那为什么addAll方法也会造成这样的结果呢 直接百度  查!

集合中关于addAll的一些问题

通过查找 这个值类型和引用类型 引起了我的注意  继续查

java中ArrayList的addAll方法添加引用类型对象时值会修改 

list的addAll方法是浅拷贝

之后又引出了一个新的概念  什么是浅拷贝 查~~~~~~

List 复制之 浅拷贝与深拷贝

才弄懂了我之前的问题产生的原因

当集合List使用引用类型的时候  举个例子 

探讨java 值引用和对象引用在addAll方法下的不同_第2张图片

引用类型就是这个MuliiInfo这个对象  

改变List.get(0).getRealName的值 是会改变这个ReFreshBean的值

原因在于 你的ReFreshBean对象在初始化的时候开开辟的内存地址是 0x00000(打个比方)List在赋值的时候 引用的是ReFreshBean这个对象   他们引用的对象的值是一样的  指向了同一个内存地址

所以不管你修改集合List.get(0).getRealName的值  还是ReFreshBean的值  2个都会变为最后修改的值

但是当集合使用值类型的时候 改变集合的值 是不会改变这个引用类型的值的 再举个值的例子

探讨java 值引用和对象引用在addAll方法下的不同_第3张图片

用基本类型值传递的时候 你修改值 集合是不会变的 

理解了这个基础的问题  看来我的基础不是很牢啊  下面来最终解决 addAll的问题

java List深拷贝的两种方式

下面这个方法 放在工具类中
 /***
     * 方法一对集合进行深拷贝 注意需要对泛型类进行序列化(实现Serializable)
     *
     * @param srcList
     * @param 
     * @return
     */
    public static  List depCopy(List srcList) {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        try {
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(srcList);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream inStream = new ObjectInputStream(byteIn);
            List destList = (List) inStream.readObject();
            return destList;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

之后使用方法 

探讨java 值引用和对象引用在addAll方法下的不同_第4张图片

就可以代替addAll方法了 

你可能感兴趣的:(探讨java 值引用和对象引用在addAll方法下的不同)