Java オブジェクトのclone 概要
2009/06/02 17:18Update
Java プログラミングを行う際、同じ型のオブジェクトからオブジェクトへ値の複製処理をしたい時はたまたまあります。setter/getterメソッドで一個一個セットするのも一つの手ですが、値が多くなると、すごく煩雑です。そこで、Java clone(クローン)技術を利用すれば、簡単にできます。
はじめに
そもそも、Java cloneとは何でしょうか。
次の例からみてみます。
Test.javapublic class Test {
public void someMethod() {
super.clone();
}
}
明らかに、clone()というメソッドはどこでも定義されていないし、Java IDEやコマンドラインから上のファイルをコンパイルしてみると、エラーにならないことを気づいたでしょうか。
super.clone()は何でしょう?
Java言語は、デフォルトではすべてのクラスはjava.lang.Objectから継承しているとみなされます。なるほど、superはObjectのことで、clone()はObjectクラスのメソッドですね。
Java言語は、java.lang.Object#clone()を通して、オブジェクトのクローン機能をサポートします。
しかし、そのままclone()メソッドを利用しようとしてもクローンできません。
Java clone()でオブジェクトのクローン
まず、以下の例から見てみます。
public class TestClone {
public static void main(String[] args) {
MyClone myClone1 = new MyClone("clone1");
MyClone myClone2 = (MyClone)myClone1.clone();
if (myClone2 != null) {
System.out.println(myClone2.getName());
System.out.println("myClone2 equals myClone1: " + myClone2.equals(myClone1));
} else {
System.out.println("Clone Not Supported");
}
}
}
class MyClone {
private String name;
public MyClone(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
実行:
C:\clone>javac *.java
C:\clone>java TestClone
Clone Not Supported
C:\clone>
結果で示したとおり、CloneNotSupportedException が投げられ、クローン機能がサポートされていません。C:\clone>java TestClone
Clone Not Supported
C:\clone>
以下の手順で、クローン機能を有効することができます。
1)Object#clone()のオーバーライド。
protected Object clone() throws CloneNotSupportedException
外部クラスからも呼ばれるようにするため、protected修飾子をpublicに変換する必要があります。
2)java.lang.Cloneableインターフェースの実装。
Cloneableは、「クローン機能をサポートするよ」とのことをJavaに知らせるために、ただの空のインタフェースです。
なので、上のサンプルのMyCloneクラス定義を以下のように変更するだけで、クローン機能を持たせることができます。
class MyClone implements Cloneable {
...//その他 そのまま・・変更なし
}
実行:
C:\clone>javac *.java
C:\clone>java TestClone
clone1
myClone2 equals myClone1: false
C:\clone>
実行結果からみますと、C:\clone>java TestClone
clone1
myClone2 equals myClone1: false
C:\clone>
1)2つオブジェクトのフィールド値は同じ値である(myClone1.name = myClone2.name = "clone1")
2)それぞれ違うインスタンスである(myClone1≠myClone2)
であることをわかりました。
まとめ
クラスAはクローン機能を提供したい場合、java.lang.Cloneableインタフェースを実装し、java.lang.Object#clone()をオーバーライドすればよい。
public class A extends Cloneable {
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
//throw (new InternalError(e.getMessage()));
return null;
}
}
}
参考資料
java.lang.Object Javadoc
(API仕様)
Sponsored Link
Comments
- Relative Articles
- Java開発及び実行環境の構築 | Linux篇 - (2008/08/31 20:34)
- Java開発及び実行環境の構築 | Windows篇 - (2008/08/31 21:18)
- 5分でJava Hello World! - (2008/08/31 22:13)
- Java言語の制御構文 - 条件分岐if/else/else if - (2008/10/01 21:30)
- Java言語の繰り返し制御構文 - for文 - (2008/10/03 18:22)
- Java言語の繰り返し制御構文 - do ... while文 - (2008/10/03 21:23)
- Java言語の繰り返し制御構文 - while文 - (2008/10/03 21:32)
- Java言語の基礎 - javacコマンドによるコンパイル - (2008/10/10 17:58)
- Java アクセス修飾子概要 - (2008/10/29 18:31)
- Javaアノテーション機能 概要 - (2009/02/12 13:06)