欢迎访问宙启技术站
智能推送

使用Java函数实现对象克隆的方式

发布时间:2023-06-30 19:40:17

在Java中,实现对象克隆有两种方式:浅克隆和深克隆。

1. 浅克隆(Shallow Cloning):

浅克隆是指创建一个新的对象,将原始对象的字段值复制给新的对象。复制的过程是在堆中创建一个新对象,并将原始对象的非静态字段的值复制给新对象。如果对象中有引用类型的字段,则只是将引用的地址进行了复制,而没有复制引用对象本身,因此原始对象和克隆对象之间还是共享同一个引用对象。浅克隆使用Java的clone()方法来实现。

下面是一个示例代码:

class TestObject implements Cloneable {

    private int value;

    

    public TestObject(int value) {

        this.value = value;

    }

    

    public int getValue() {

        return value;

    }

    

    public void setValue(int value) {

        this.value = value;

    }

    

    @Override

    public Object clone() throws CloneNotSupportedException {

        return super.clone();

    }

}

public class Main {

    public static void main(String[] args) {

        TestObject obj1 = new TestObject(10);

        

        try {

            TestObject obj2 = (TestObject) obj1.clone();

            System.out.println("obj1 value: " + obj1.getValue());

            System.out.println("obj2 value: " + obj2.getValue());

            

            obj2.setValue(20);

            System.out.println("obj1 value: " + obj1.getValue());

            System.out.println("obj2 value: " + obj2.getValue());

        } catch (CloneNotSupportedException e) {

            e.printStackTrace();

        }

    }

}

输出结果为:

obj1 value: 10

obj2 value: 10

obj1 value: 10

obj2 value: 20

可以看到,改变克隆对象的值不会影响原始对象的值,因为它们是独立的对象。但是,通过obj1和obj2的setValue方法改变原始对象或克隆对象的值都会相互影响,因为它们共享同一个引用对象。

2. 深克隆(Deep Cloning):

深克隆是指创建一个新的对象,将原始对象的字段值复制给新的对象,并将原始对象中的引用类型字段也进行克隆。也就是说,深克隆会递归地复制一个对象及其引用对象的所有内容。深克隆需要实现Serializable接口,并使用Java的序列化和反序列化来实现。

下面是一个示例代码:

import java.io.*;

class TestObject implements Serializable {

    private int value;

    private DeepCloneObject deepCloneObj;

    

    public TestObject(int value, DeepCloneObject deepCloneObj) {

        this.value = value;

        this.deepCloneObj = deepCloneObj;

    }

    

    public int getValue() {

        return value;

    }

    

    public DeepCloneObject getDeepCloneObj() {

        return deepCloneObj;

    }

    

    public void setValue(int value) {

        this.value = value;

    }

    

    public void setDeepCloneObj(DeepCloneObject deepCloneObj) {

        this.deepCloneObj = deepCloneObj;

    }

    

    public TestObject deepClone() throws IOException, ClassNotFoundException {

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        ObjectOutputStream oos = new ObjectOutputStream(bos);

        oos.writeObject(this);

        

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

        ObjectInputStream ois = new ObjectInputStream(bis);

        return (TestObject) ois.readObject();

    }

}

class DeepCloneObject implements Serializable {

    private String name;

    

    public DeepCloneObject(String name) {

        this.name = name;

    }

    

    public String getName() {

        return name;

    }

    

    public void setName(String name) {

        this.name = name;

    }

}

public class Main {

    public static void main(String[] args) {

        DeepCloneObject deepCloneObj = new DeepCloneObject("DeepCloneObject");

        TestObject obj1 = new TestObject(10, deepCloneObj);

        

        try {

            TestObject obj2 = obj1.deepClone();

            System.out.println("obj1 value: " + obj1.getValue());

            System.out.println("obj2 value: " + obj2.getValue());

            System.out.println("obj1 deepCloneObj name: " + obj1.getDeepCloneObj().getName());

            System.out.println("obj2 deepCloneObj name: " + obj2.getDeepCloneObj().getName());

            

            obj2.setValue(20);

            obj2.getDeepCloneObj().setName("Modified DeepCloneObject");

            System.out.println("obj1 value: " + obj1.getValue());

            System.out.println("obj2 value: " + obj2.getValue());

            System.out.println("obj1 deepCloneObj name: " + obj1.getDeepCloneObj().getName());

            System.out.println("obj2 deepCloneObj name: " + obj2.getDeepCloneObj().getName());

        } catch (IOException | ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

}

输出结果为:

obj1 value: 10

obj2 value: 10

obj1 deepCloneObj name: DeepCloneObject

obj2 deepCloneObj name: DeepCloneObject

obj1 value: 10

obj2 value: 20

obj1 deepCloneObj name: DeepCloneObject

obj2 deepCloneObj name: Modified DeepCloneObject

可以看到,改变克隆对象的值不会影响原始对象的值,而且它们引用的深克隆对象也是独立的,互相之间不会相互影响。

通过上述示例代码,我们可以了解到,在Java中实现对象克隆有两种方式:浅克隆和深克隆。选择合适的克隆方式取决于需要的对象关系以及字段的复杂程度。