侧边栏壁纸
博主头像
实习两年半

基础不牢,地动山摇。

  • 累计撰写 43 篇文章
  • 累计创建 40 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Java对象拷贝

实习两年半
2022-06-11 / 0 评论 / 0 点赞 / 473 阅读 / 790 字
温馨提示:
本文最后更新于 2022-06-12,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

拷贝的概念

 java中拷贝分为深拷贝浅拷贝,对于基本数据类型拷贝的都是其值,而对于引用类型,拷贝的也是值,只不过引用类型拷贝的值是一个地址(java中只有值传递),对象还是原来的对象,这就是浅拷贝

 也可以从内存上来说明,比如对象A,其是一个地址,存放在栈内。此时对A进行拷贝一份未B对象。如果是浅拷贝,那么B对象与A对象它们都指向一个相同地址。如果是深拷贝,A与B的对象指向的地址不一样,但其指向地址内的数据是一样的。
{mtitle title="浅拷贝"/}
浅拷贝
{mtitle title="深拷贝"/}
深拷贝

Object类中clone()方法

  1. 实现Cloneable接口
  2. 重写clone()接口,super.clone();
public class Student  implements Cloneable{
    private String name;
    private Integer age;

    private Address address;

    @Override
    protected Student clone() throws CloneNotSupportedException {
        return (Student)super.clone();
    }

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

    public Address getAddress() {
        return address;
    }

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

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}
public class Address{
    private String name;

    public Address(String name) {
        this.name = name;
    }

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

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Address{" +
                "name='" + name + '\'' +
                '}';
    }
}

测试类

public class CopyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student stu = new Student();
        stu.setName("cwl");
        stu.setAge(18);
        Address address = new Address("南京");
        stu.setAddress(address);

        Student cloneStu = stu.clone();
        System.out.println(stu);
        System.out.println(cloneStu);
        System.out.println(stu == cloneStu);

    }
}
// 运行结果
Student{name='cwl', age=18, address=Address{name='南京'}}
Student{name='cwl', age=18, address=Address{name='南京'}}
false

 此时我们对address对象修改内容观察结果

public class CopyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student stu = new Student();
        stu.setName("cwl");
        stu.setAge(18);
        Address address = new Address("南京");
        stu.setAddress(address);

        Student cloneStu = stu.clone();
        cloneStu.getAddress().setName("苏州");
        System.out.println(stu);
        System.out.println(cloneStu);
    }
}
// 运行结果
Student{name='cwl', age=18, address=Address{name='苏州'}}
Student{name='cwl', age=18, address=Address{name='苏州'}}

 此时会发现,修改cloneStu对象中的address内容,原对象stu中的内容也发生了改变,所以这种克隆方式为浅克隆(浅拷贝)。

深拷贝的方式

通过流进行拷贝

注意: 拷贝的类包括其属性为引用属性都要实现Serializable接口,否则报错

    /**
     * 流拷贝
     * @param obj
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Object streamCopy(Object obj) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(obj);
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return ois.readObject();
    }

使用fastjson复制

添加依赖

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.1.71.android</version>
</dependency>
public static void main(String[] args) throws  IOException{
    Student stu = new Student();
    stu.setName("cwl");
    stu.setAge(18);
    Address address = new Address("南京");
    stu.setAddress(address);

    String str = JSON.toJSONString(stu);
    Student cloneStu = JSON.parseObject(str, Student.class);

    cloneStu.getAddress().setName("苏州");
    System.out.println(stu);
    System.out.println(cloneStu);
}

这两种测试结果都为

Student{name='cwl', age=18, address=Address{name='南京'}}
Student{name='cwl', age=18, address=Address{name='苏州'}}
0

评论区