Java淺複製大揭秘:如何輕鬆複製兩個不同物件的某些相同屬性

木头左發表於2024-05-29

哈嘍,大家好,我是木頭左!

一、引言

在Java程式設計中,經常會遇到需要複製一個物件的屬性到另一個物件的情況。這時,可以使用淺複製(Shallow Copy)來實現這個需求。那麼,什麼是淺複製呢?淺複製是指建立一個新物件,然後將原物件的非靜態欄位複製到新物件中。這樣,新物件和原物件就會有相同的欄位值。本文將詳細介紹如何使用Java實現淺複製,並給出程式碼示例。

二、淺複製的原理

淺複製的實現原理是透過呼叫物件的clone()方法來實現的。clone()方法是Object類的一個方法,所有Java類都繼承自Object類,因此都可以呼叫clone()方法。當呼叫一個物件的clone()方法時,會建立一個新的物件,並將原物件的非靜態欄位複製到新物件中。需要注意的是,如果欄位是引用型別,那麼只會複製引用,而不會複製引用指向的物件。這就是淺複製的特點。

三、實現淺複製的方法

1. 使用clone()方法

要使用clone()方法實現淺複製,首先需要讓原物件實現Cloneable介面,並重寫clone()方法。下面是一個簡單的示例:

class Person implements Cloneable {
    private String name;
    private int age;

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

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

    // getter和setter方法省略
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("張三", 25);
        try {
            Person p2 = (Person) p1.clone();
            System.out.println("p1: " + p1.getName() + ", " + p1.getAge());
            System.out.println("p2: " + p2.getName() + ", " + p2.getAge());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

執行結果:

p1: 張三, 25
p2: 張三, 25

從執行結果可以看出,使用clone()方法實現了淺複製。但是,這種方法有一個缺點,就是無法實現深複製。因為當欄位是引用型別時,clone()方法只會複製引用,而不會複製引用指向的物件。這就導致了淺複製後的新物件和原物件共享同一個引用型別的欄位。

2. 使用序列化和反序列化實現淺複製

序列化是將物件轉換為位元組流的過程,反序列化是將位元組流轉換回物件的過程。透過序列化和反序列化可以實現物件的深複製。但是,這種方法只適用於實現了Serializable介面的物件。下面是一個簡單的示例:

import java.io.*;

class Person implements Serializable {
    private String name;
    private int age;

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

    // getter和setter方法省略
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("張三", 25);
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(p1);
            oos.flush();
            oos.close();
            bos.close();

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            Person p2 = (Person) ois.readObject();
            System.out.println("p1: " + p1.getName() + ", " + p1.getAge());
            System.out.println("p2: " + p2.getName() + ", " + p2.getAge());
            ois.close();
            bis.close();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

執行結果:

p1: 張三, 25
p2: 張三, 25

從執行結果可以看出,使用序列化和反序列化實現了淺複製。但是,這種方法的缺點是效能較差,因為序列化和反序列化的過程比較耗時。此外,這種方法還需要物件實現Serializable介面,限制了其適用範圍。

四、總結

本文詳細介紹瞭如何使用Java實現淺複製,並給出了程式碼示例。介紹了兩種實現淺複製的方法:使用clone()方法和序列化與反序列化。雖然這兩種方法都可以實現淺複製,但它們各有優缺點。使用clone()方法實現淺複製簡單易用,但無法實現深複製;而使用序列化與反序列化實現淺複製效能較好,但需要物件實現Serializable介面,限制了其適用範圍。在實際開發中,需要根據具體需求選擇合適的方法來實現淺複製。

我是木頭左,感謝各位童鞋的點贊、收藏,我們下期更精彩!

相關文章