深拷贝,浅拷贝

浅拷贝:只拷贝基本类型的属性,引用类型的属性将地址付给新对象,所以浅拷贝后修改基本类型属性两个对象不会影响,修改引用类型属性会互相影响.浅拷贝可以用cloneable接口的clone方法实现,也可以用spring的 BeanUtils.copyProperties方法实现

深拷贝:基本类型和引用类型的属性都是真正的拷贝,所以深拷贝后修改基本类型和引用类型的属性都不会互相影响

浅拷贝实现代码:

package kun.copy;

public class Address {

    String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
}
package kun.copy;

public class Person implements  Cloneable{
 
     int num;
     String name;
     Address address;
 
    public Person() {
    }
 
    public Person(int num, String name) {
        this.num = num;
        this.name = name;
    }
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Address getAddress() {
        return address;
    }
 
    public void setAddress(Address address) {
        this.address = address;
    }
 
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
        return person;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

 

package kun.copy;

import org.springframework.beans.BeanUtils;

public class Test {
 
    public static void main(String[] args) throws CloneNotSupportedException {
        //测试浅拷贝
        Address address = new Address();
        address.setAddress("汉中");
        Person p1 = new Person(100, "jim");
        p1.setAddress(address);
        Person p2 = p1.clone();
        p1.setNum(99);//修改p1对象中基本类型属性,不会影响p2
        p2.setName("tom");//修改p2对象中基本类型属性,不会影响p1
        p1.getAddress().setAddress("西安"); //浅拷贝不复制引用类型属性,只是将地址赋给新对象,所以修改p1中引用属性的值会影响p2
        System.out.println(p1); // 99 jim   西安
        System.out.println(p2);// 100 tom    西安
    }
}
package kun.copy;

import org.springframework.beans.BeanUtils;

public class TestBeanUtil {
 
    public static void main(String[] args) throws CloneNotSupportedException {
//spring的 BeanUtils.copyProperties的浅拷贝
        Address address = new Address();
        address.setAddress("汉中");
        Person p1 = new Person(100, "jim");
        p1.setAddress(address);
  Person p2 = new Person();
BeanUtils.copyProperties(p1,p2);
 p1.setNum(99);//修改p1对象中基本类型属性,不会影响p2 p2.setName("tom");//修改p2对象中基本类型属性,不会影响p1 p1.getAddress().setAddress("西安"); //浅拷贝不复制引用类型属性,只是将地址赋给新对象,所以修改p1中引用属性的值会影响p2 System.out.println(p1); // 99 jim 西安 System.out.println(p2);// 100 tom 西安  } }

深拷贝自己实现代码(也可用第三方提供的工具类):

package kun.copy;

import java.io.Serializable;

public class Address2 implements Serializable {
 
     String  address;
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        this.address = address;
    }
 
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
 
}
package kun.copy;

import java.io.*;

public class Person2 implements Serializable {
 
     int num;
     String name;
     Address2 address;
 
    public Person2() {
    }
 
    public Person2(int num, String name) {
        this.num = num;
        this.name = name;
    }
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }

    public Address2 getAddress() {
        return address;
    }

    public void setAddress(Address2 address) {
        this.address = address;
    }

    /**
     * 自定义克隆方法
     * @return
     */
    public Person2 myclone() {
            Person2 person2 = null;
              try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
                      ObjectOutputStream oos = new ObjectOutputStream(baos);
                      oos.writeObject(this);
            // 将流序列化成对象
                    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                     ObjectInputStream ois = new ObjectInputStream(bais);
                     person2 = (Person2) ois.readObject();
                  } catch (IOException e) {
                     e.printStackTrace();
                  } catch (ClassNotFoundException e) {
                     e.printStackTrace();
                 }
             return person2;
          }
 
 
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}
package kun.copy;

import kun.copy.Person;

public class TestDeepCopy {
 
    public static void main(String[] args) throws CloneNotSupportedException {

        Address2 address = new Address2();
        address.setAddress("汉中");

        Person2 p1 = new Person2(100, "jim");
        p1.setAddress(address);

        Person2 p2 = p1.myclone();
        p1.setNum(99);
        p2.setName("tom");
        p2.getAddress().setAddress("西安");//深拷贝中将引用类型属性也实现真正的拷贝,所以修改p2的引用属性不会影响p1

        System.out.println(p1); // 99,jim 汉中
        System.out.println(p2); // 100,tom 西安
    }
}

 

posted @ 2023-06-04 16:20  杨吃羊  阅读(23)  评论(0)    收藏  举报