美文网首页java高级java基础
简析Java的浅拷贝和深拷贝

简析Java的浅拷贝和深拷贝

作者: erki_stwee | 来源:发表于2018-05-16 00:31 被阅读1次

浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值。
深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。

更通俗的描述:浅拷贝只复制一个对象,传递引用,不能复制实例。深拷贝对对象内部的引用均复制,它是创建一个新的实例,并且复制实例。

注意:如果变量都是基本数据类型;浅拷贝跟深拷贝都是一样的。

public class Person {

    private String name;
    private String sex;
    private int age;

    public Person(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public Person(Person person){
        this.name = person.name;
        this.sex = person.sex;
        this.age = person.age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}


public class Asian {

    private String skin;
    Person mPerson;

    public Asian(String skin, Person person) {
        this.skin = skin;
        mPerson = person;
    }

    public Asian(Asian asian){
        this(asian.skin,asian.mPerson);
    }

    public static void main(String [] args){
        Person person = new Person("Uart", "men", 23);
        Person person1 = new Person(person);

        System.out.println(person.toString());
        System.out.println(person1.toString());
        System.out.println(person1 == person);

        Asian a1 = new Asian("yellow", new Person("Uart", "men", 23));
        Asian a2 = new Asian(a1);

        System.out.println(a1.toString());
        System.out.println(a2.toString());
        System.out.println(a1 == a2);

        System.out.println(person.getName());
        System.out.println(person1.getName());
        System.out.println(person.getName() == person1.getName());

        person.setName("Jhon");

        //String是不可变对象,在拷贝的时候会被复制
        System.out.println(person.getName());
        System.out.println(person1.getName());
        System.out.println(person.getName() == person1.getName());

    }
}

总结:
1.基本类型
如果变量是基本类型,则拷贝它的值,比如int、float等;
2.对象
如果变量是一个实例对象,则拷贝其地址引用。也就是说新对象与旧对象指向同一个地址引用
3.String字符串
String是不可变对象,在拷贝的时候会被复制。

扩展知识

利用序列化实现对象的拷贝
直接上代码

使用该方法无需继承Cloneable接口实现clone()方法;该工具类的对象只要实现Serializable接口就可以实现对象的克隆。
public static <Object extends Serializable> Object clone(Object object){
        Object cloneObj = null;
        try{
            //写入字节流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream obs = new ObjectOutputStream(out);
            obs.writeObject(cloneObj);
            obs.close();
                
            //分配内存,写入原始数据,生成新对象
            ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(ios);
            cloneObj = (Object) ois.readObject();
            ois.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return cloneObj;
    }

补充
浅拷贝例子

//获取真实数据
        GetDateList getDateList = new GetDateList();
        //获取当前年份数据(寿命期与年公用同一份数据)
        year = getDateList.getYear();
        //第一次进来展示最新数据
        month = getDateList.getMonth(year.get(year.size() - 1));
        //第一次进来展示当前天数
        day = getDateList.getDay(year.get(year.size() - 1));

        Log.e("TAG", "year地址值 : " + year + "   month地址值 : " + month + "   day地址值 : " + day);

 /**
     * 获取真实数据
     * @param year
     * @param month
     * @param day
     */
    private void getRealDate(ArrayList<Long> year, ArrayList<Long> month, ArrayList<Long> day) {
        switch (type) {
            case 2 :
            case 3 :
                list = year;
                break;
            case 1 :
                list = month;
                break;
            case 0 :
                list = day;
                break;
        }
    }


 @Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
        switch (checkedId) {
            case  R.id.radio_day:
                type = 0;
                list.clear();
                Log.e("TAG   radio_day", "year地址值 : " + year + "   month地址值 : " + month + "   day地址值 : " + day);
                getRealDate(year, month, day);
                adapter.setList(list);
                adapter.setType(type);
                adapter.getClickList().clear();
                adapter.notifyDataSetChanged();
                break;
            case R.id.radio_month:
                type = 1;
                list.clear();
                Log.e("TAG  radio_month", "year地址值 : " + year + "   month地址值 : " + month + "   day地址值 : " + day);
                getRealDate(year, month, day);
                adapter.setList(list);
                adapter.setType(type);
                adapter.getClickList().clear();
                adapter.notifyDataSetChanged();
                break;
            case R.id.radio_year:
                type = 2;
                list.clear();
                Log.e("TAG  radio_year", "year地址值 : " + year + "   month地址值 : " + month + "   day地址值 : " + day);
                getRealDate(year, month, day);
                adapter.setList(list);
                adapter.setType(type);
                adapter.getClickList().clear();
                adapter.notifyDataSetChanged();
                break;
            case R.id.radio_total:
                type = 3;
                list.clear();
                Log.e("TAG   radio_total", "year地址值 : " + year + "   month地址值 : " + month + "   day地址值 : " + day);
                getRealDate(year, month, day);
                adapter.setList(list);
                adapter.setType(type);
                adapter.getClickList().clear();
                adapter.notifyDataSetChanged();
                break;
        }
    }
浅拷贝效果图.PNG

这是因为浅拷贝导致数据clear原始数据也被clear。这里最简单的修改方式是addAll而不采用直接 =来赋值

相关文章

  • java 对象的拷贝

    拷贝:即复制 对象拷贝:即对象复制 java 对象拷贝分类:浅拷贝、深拷贝 java 对象的浅拷贝和深拷贝针对包含...

  • Java基础 - 深拷贝和浅拷贝

    Java 的深拷贝和浅拷贝 什么是深拷贝、浅拷贝 (深克隆、浅克隆)? 在 Java 中,数据类型分为 基本数据类...

  • 简析Java的浅拷贝和深拷贝

    浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值。深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

  • Java的深拷贝和浅拷贝深析

    点击进入博客 最近在公司的项目中用到了Java的对象拷贝(Object Copy),准备深入了解一下,试想一下如果...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • Java------List的深拷贝与浅拷贝

    Java的浅拷贝(Shallow Copy)、深拷贝(Deep Copy)。 浅拷贝(Shallow Copy) ...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • Java的浅拷贝和深拷贝

    首先需要明白,浅拷贝和深拷贝都是针对一个已有对象的操作。那先来看看浅拷贝和深拷贝的概念。 在 Java 中,除了基...

  • 深克隆--何时是尽头?

    As we all know Java有两种拷贝,浅拷贝和深拷贝,高大上的叫法也叫浅克隆和深克隆。 深克隆有时会碰...

网友评论

    本文标题:简析Java的浅拷贝和深拷贝

    本文链接:https://www.haomeiwen.com/subject/tzwydftx.html