PHASE2 LOG

主にIT関連・ゲームのログ

Javaのお勉強~シャローコピーとディープコピー~

      2016/03/12

今回はオブジェクトの複製についてお勉強してみます。

前回の記事に書いたObjectクラスにはいくつかのメソッドが用意されています。

その1つであるclone()メソッドを使います。

 

clone()メソッド

 

Objectクラスのメソッドであるclone()メソッドオブジェクトの複製(クローン)を作るメソッドです。

Objectクラスのメソッドなので、すべてのクラスに継承されています。

 

ただし、clone()メソッドを使用するためには、Cloneableインタフェースを実装する必要があります。

 

 

参照型について

 

clone()メソッドでは、int型やlong型などの基本データ型と呼ばれる変数はその実体が複製されます。

 

しかし、String型のようなクラス型変数その実体の場所を指す情報が格納されています。

このような変数を参照型といいます。

 

このことを踏まえてシャローコピーとディープコピーの違いを説明します。

 

シャローコピーとは

 

さきほどの参照型の変数をclone()メソッドで複製(コピー)すると、参照先の情報だけが複製されます。

ということは複製元と複製先で、同じ場所を参照していることになりますね。

 

つまり、同じ場所にある変数を共有することになります。

複製元でも複製先でもどちらか一方でデータを書き換えると、もう片方のデータも書き換えられちゃいます。

これをシャローコピーといいます。

 

これって不便ですよね…

そこでディープコピーを使います。

 

ディープコピーとは

 

シャローコピーでは複製の関係にあるものに変更があるとすべてに影響しちゃいますね。

 

なのでclone()メソッドを利用する際に、publicをつけてclone()メソッドをオーバーライドします。

そしてひとつひとつのメンバを複製することをディープコピーといいます。

 

ディープコピーの実際の例がこちらです。

//Cloneableインタフェースを実装
class Member implements Cloneable {
	String name;
	int HP;
	
	//ディープコピー
	public Object clone() {
		Member tida = new Member();
		tida.name = new String(name);
		tida.HP = HP;
		return (tida);
	}
}

public class Deepcopy {
	public static void main(String[] args){
		//aは複製元
		Member a = new Member();
		a.name = "Tida";
		
		//bはaを複製したもの
		Member b = (Member)a.clone();
		b.name = "Yuna";
		
		//ディープコピーなのでそれぞれのnameで書き換えられる
		System.out.println(a.name);
		System.out.println(b.name);
	}
}

 

上記ではclone()メソッドをpublicをつけてオーバーライドしているので、

複製した際にもaとbのnameは別々の参照先になっています。

 

なので、aにTidaを設定して、bでYunaに書き換えてもどちらも保持されています!

 

ディープコピーとシャローコピーの違いはこんな感じですかね。

deepshallow

 

もし、例に書いたソースがシャローコピーであれば、aでTidaに設定したあと、bでYunaに書き換えると

同じnameが参照されているのでどちらもYunaになってしまいますね。

 

ディープコピーとシャローコピーはばっちり押さえられた気がします(´∀`)

 

人気ブログランキング

 -