专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

java基础篇-实现对象克隆4种方法

54_1.png

1. 前言

今天学习了java实现拷贝的四种方式,这里记录一下。

2. 正文

Java实现对象克隆的四种方法

(1)将A对象的值分别通过set方法加入B对象中;

(2)通过重写java.lang.Object类中的方法clone();

(3)通过org.apache.commons中的工具类BeanUtils进行对象复制;

(4)通过序列化实现对象的复制。

2.1 将A对象的值分别通过set方法加入B对象中

如果属性少的话就这样可以达到目的,可是一旦修改了Student类,每一处克隆都要额外添加set get方法,将非常繁琐

Student stu1 = new Student();  
stu1.setNumber(12345);  
Student stu2 = new Student();  
stu2.setNumber(stu1.getNumber());

2.2 重写java.lang.Object类中的方法clone()

浅克隆(ShallowClone)

1、 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常)
2、 覆盖clone()方法,访问修饰符设为public。直接调用父类的clone方法

class Student implements Cloneable{  
    private int number;  

    public int getNumber() {  
        return number;  
    }  

    public void setNumber(int number) {  
        this.number = number;  
    }  

    @Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        return stu;  
    }  
}  
// 测试:public class Main {
    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.setNumber(1529786);
        Student stu2 = (Student)stu1.clone();

        System.out.println("学生1:" + stu1.getNumber());
        System.out.println("学生2:" + stu2.getNumber());

        stu2.setNumber(1571707);

        System.out.println("学生1:" + stu1.getNumber());
        System.out.println("学生2:" + stu2.getNumber());
    }
}

54_2.png

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。

class Address {  
    private String add;  

    public String getAdd() {  
        return add;  
    }  

    public void setAdd(String add) {  
        this.add = add;  
    }   
}  

class Student implements Cloneable{  
    private int number;  

    private Address addr;  

    public Address getAddr() {  
        return addr;  
    }  

    public void setAddr(Address addr) {  
        this.addr = addr;  
    }  

    public int getNumber() {  
        return number;  
    }  

    public void setNumber(int number) {  
        this.number = number;  
    }  

    @Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();   //浅复制  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }   
        return stu;  
    }  
}  
public class Test {  

    public static void main(String args[]) {  

        Address addr = new Address();  
        addr.setAdd("成都市");  
        Student stu1 = new Student();  
        stu1.setNumber(123);  
        stu1.setAddr(addr);  

        Student stu2 = (Student)stu1.clone();  

        System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
        System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  

        addr.setAdd("犀浦区");  

        System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
        System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
    }  
}

54_3.png

深克隆(DeepClone)

class Address implements Cloneable {  
    private String add;  

    public String getAdd() {  
        return add;  
    }  

    public void setAdd(String add) {  
        this.add = add;  
    }  

    @Override  
    public Object clone() {  
        Address addr = null;  
        try{  
            addr = (Address)super.clone();  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        return addr;  
    }  
}  

class Student implements Cloneable{  
    private int number;  

    private Address addr;  

    public Address getAddr() {  
        return addr;  
    }  

    public void setAddr(Address addr) {  
        this.addr = addr;  
    }  

    public int getNumber() {  
        return number;  
    }  

    public void setNumber(int number) {  
        this.number = number;  
    }  

    @Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();   //浅复制  
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        stu.addr = (Address)addr.clone();   //深度复制  
        return stu;  
    }  
}  
public class Test {  

    public static void main(String args[]) {  

        Address addr = new Address();  
        addr.setAdd("杭州市");  
        Student stu1 = new Student();  
        stu1.setNumber(123);  
        stu1.setAddr(addr);  

        Student stu2 = (Student)stu1.clone();  

        System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
        System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  

        addr.setAdd("西湖区");  

        System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());  
        System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());  
    }  
}

对Student类clone方法,stu = (Student)super.clone(); 进行浅复制,然后对属性addr再进行克隆,直到所有引用类型都覆盖到

测试:

54_4.png

2.3 工具类BeanUtils进行对象复制

Student stu1 = new Student();  
stu1.setNumber(12345);  
Student stu2 = new Student(); 
BeanUtils.copyProperties(stu2,stu1);

一行代码搞定,简单粗暴,YEAH!(*^-^*)

2.4 通过序列化实现对象的复制

public class Demo2 implements Serializable {

    private String name;

    private String value;

    private DemoInternal2 demoInternal2;

    /*省略getter和setter方法*/

    // 深度复制
    public Demo2 myclone() {
        Demo2 demo2 = null;
        try {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);

            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            demo2 = (Demo2) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return demo2;
    }
}

文章永久链接:https://tech.souyunku.com/29482

未经允许不得转载:搜云库技术团队 » java基础篇-实现对象克隆4种方法

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们