「Java」Object#close でオブジェクトのクローンを作成するサンプル
Object#close を使用することでオブジェクトのクローンが生成できます。
・Object (Java Platform SE 8 )
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Object.html
ドキュメントに書いてますが Object#close を使用する場合、クローンを生成するオブジェクトのクラスが Cloneable インタフェースを実装している必要があります ( 実装していないと CloneNotSupportedException が発生する )。
・Cloneable (Java Platform SE 8 )
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Cloneable.html
あと、こちらもドキュメントに書いてますが、Object#close では可変オブジェクトへの参照を保持するフィールドについては浅いコピーになるので注意が必要です。
以下、サンプルになります。
■ CloneTest.java
package test.clone; import java.util.ArrayList; import java.util.List; public class CloneTest implements Cloneable { private int i; private String s; private List<String> l; public CloneTest(int i, String s, List<String> l) { this.i = i; this.s = s; this.l = l; } public void setI(int i) { this.i = i; } public void setS(String s) { this.s = s; } public void setL(List<String> l) { this.l = l; } public int getI() { return i; } public String getS() { return s; } public List<String> getL() { return l; } public String toString() { return "[i:" + i +"] [s:" + s + "] [l:" + l.toString() +"]"; } public static void main(String[] args) { List<String> l = new ArrayList<>(); l.add("aaa"); CloneTest inst = new CloneTest(100, "hoge", l); CloneTest clone = null; try { clone = (CloneTest)inst.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } System.out.println(inst); System.out.println(clone); // inst のフォールドを変更してみる String s = inst.getS(); s = "uga"; inst.setS(s); List<String> ll = inst.getL(); l.add("bbb"); inst.setL(l); System.out.println(inst); System.out.println(clone); } }
■ 実行結果
[i:100] [s:hoge] [l:[aaa]] [i:100] [s:hoge] [l:[aaa]] [i:100] [s:uga] [l:[aaa, bbb]] [i:100] [s:hoge] [l:[aaa, bbb]]
inst のフィールド l の変更が clone 側にも影響している様子が確認できます。
可変オブジェクトのフィールドを深いコピーにしたいという場合は、以下のような感じで Object#clone をオーバーライドしてやる必要があります。
public Object clone() throws CloneNotSupportedException { super.clone(); List<String> copy = new ArrayList<>(l); return new CloneTest(i, s, copy); }
Object#clone をオーバーライドした際のサンプルの実行結果は以下の通りです。
[i:100] [s:hoge] [l:[aaa]] [i:100] [s:hoge] [l:[aaa]] [i:100] [s:uga] [l:[aaa, bbb]] [i:100] [s:hoge] [l:[aaa]]
inst のフィールド l の変更が clone 側には影響していないことが確認できます。
簡単になりますが、以上です。