Javaのディープコピーとシャローコピーの実装方法は何ですか?
Javaにおいて、ディープコピーとシャローコピーは異なる方法で実装することができます。
- 浅いコピー:浅いコピーとは、オブジェクトをコピーする際に、オブジェクトの参照のみをコピーし、オブジェクト自体をコピーしないことを指します。そのため、一方のオブジェクトを変更すると、他のオブジェクトも影響を受ける可能性があります。
- 以下の方法で浅いコピーを実現します:
- Cloneableインターフェースを実装し、clone()メソッドをオーバーライドします。clone()メソッドでは、親クラスのclone()メソッドを呼び出し、コピーされたオブジェクトを返します。public class MyClass implements Cloneable {
private int value;public MyClass(int value) {
this.value = value;
}@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
} - copyメソッドを使用してコピーを作成します。たとえば、Arrays.copyOf()やSystem.arraycopy()を使用して配列の浅いコピーを作成できます。int[] array1 = {1, 2, 3};
int[] array2 = Arrays.copyOf(array1, array1.length); - ディープコピー:ディープコピーは、オブジェクトのコピー時に、オブジェクトの参照だけでなく、オブジェクト自体とそれが参照するすべてのオブジェクトをコピーすることを指します。これにより、コピー後のオブジェクトの変更が元のオブジェクトに影響を与えないようになります。
- 以下の方法を使用して深いコピーを実行します。
- Serializableインターフェースを実装し、シリアライズとデシリアライズを使用して、深いコピーを実現します。import java.io.*;public class MyClass implements Serializable {
private int value;public MyClass(int value) {
this.value = value;
}public MyClass deepCopy() throws IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
MyClass copy = (MyClass) ois.readObject();
ois.close();return copy;
}
} - Apache Commons LangのSerializationUtils.clone()メソッドなどのサードパーティーライブラリを使用して、ディープコピーを行います。MyClass copy = SerializationUtils.clone(original);
注意すべきは、オブジェクトがコピー可能になるためには、以下の条件のいずれかを満たす必要があることです。
- そのオブジェクトは、Cloneableインタフェースを実装してclone()メソッドをオーバーライドする必要があります。
- そのオブジェクトはSerializableインターフェースを実装しています。
- サードパーティのライブラリーが提供するディープコピーのメソッドを使用してください。