由公共数据被修改引发的JAVA引用回顾

2017-12-19  本文已影响5人  dlihasa

在开发过程中,有时会忽略了一些非常基础的java基础,很尴尬。

问题源头:在个人信息选择地区和对对方的地区要求(择偶要求)中数据相差了一个“不限”,也就是说现在有一套json数据(或者其他形式),但是在不同的地方用的时候可能需要动态添加部分信息。
在应用启动开启一个子线程将数据解析成需要的list形式,然后在择偶要求中获取到list然后进行了动态修改,而在这儿就犯了一个低级错误:获取的时候我直接赋值给了新的list,对的,直接赋值。。

List<bean> cityArea = Application.area;

由于是地址的赋值,那么他们所代表的对象都是同一个对象,这样必然会导致后续对cityArea 的修改会改变公共数据Application.area。。

对引用的回忆开启

       /**
         * 对对象的直接赋值以及修改
         */
        Body a = new Body("111","男");
        Body b = a;
        b.setName("222");
        System.out.println(a.getName());
        System.out.println("-------------------------");
        /**
         * 构造一个list的对象
         */
        ArrayList<Body> list1 = new ArrayList<Body>();
        list1.add(new Body("111","man"));
        list1.add(new Body("111","man"));
        list1.add(new Body("111","man"));
        /**
         * 克隆一个list
         */
        ArrayList<Body> listcopy = (ArrayList<Body>) list1.clone();
        /**
         * 重新创建一个list,将之前的list添加进来
         */
        ArrayList<Body> list11 = new ArrayList<Body>();
        list11.addAll(list1);
        /**
         * 直接将一个list赋值给另外一个list
         */
        ArrayList<Body> list00 = list1;
        
        /**
         * 修改被赋值的list
         */
        list00.add(new Body("222","woman"));
        list00.get(0).setName("修改后的名字");
        
        System.out.println("浅克隆的listcopy:"+listcopy.size()+"  第一个名字:"+listcopy.get(0).getName());
        System.out.println("原list1:"+list1.size()+"  第一个名字:"+list1.get(0).getName());
        System.out.println("新list11:"+list11.size()+"  第一个名字:"+list11.get(0).getName());
        System.out.println("被赋值的list00:"+list00.size()+"  第一个名字:"+list00.get(0).getName());

        System.out.println("---------------------------");

打印输出结果如下:

222
-------------------------
浅克隆的listcopy:3  第一个名字:修改后的名字
原list1:4  第一个名字:修改后的名字
新list11:3  第一个名字:修改后的名字
被赋值的list00:4  第一个名字:修改后的名字
---------------------------

知识点简单却被忽略
1、对象直接赋值,自然都是指向了同一对象,对它的修改实际就是对他们唯一的对象的修改。
2、java的克隆首先分配一个和原对象同样大小的空间(注意有分配新的内存空间哦),然后再使用原对象中对应的各个域,填充新对象的域,这里的浅克隆是对list克隆了,但是list内每个对象还是原来的对象。(深克隆也很简单)
3、新建一个list(注意有分配新的内存空间哦),然后将原来的list全部add进去。
4、将原来的list直接赋值给一个list(注意并没有重新分配内存)
首先,每个原list内部的对象都是最初的那几个,不管是通过哪个list修改他们,自然都会改变。

然后呢,2和3中因为list都是新分配内存的(其实可以理解为2和3中也保存了一份原list内指向那些对象的引用(地址)),所以对原来list的操作并不会影响到他们。

JAVA引用专门的讲解附上一篇吧
https://www.cnblogs.com/dolphin0520/p/3592498.html
深克隆与浅克隆同样附上一篇
https://www.cnblogs.com/acode/p/6306887.html

上一篇 下一篇

猜你喜欢

热点阅读