365連休

にわかのandroidとかの開発メモ。

Javaでfinal宣言されたミュータブルオブジェクトをメンバに持つクラスはcloneできない

以下、私見です。

ミュータブルはCollectionなどの事、イミュータブルはStringなどの事

 

Javaのcloneはオブジェクト構造のコピーが作られる。

構造体のコピーみたいな感じ。

 

Javaにおいてプリミティブ値は参照を持たないから値がコピーされ、

オブジェクトは参照だけがコピーされる。

 

ここで、clone対象のメンバ変数に書き換え不可能なオブジェクト(イミュータブル)を持つ場合は、参照がコピーされても以前と同じ動作をするため問題無いが、

clone対象のメンバ変数に書き換え可能なオブジェクト(ミュータブル)を持つ場合は、参照がコピーされただけではクラスの動作に問題が生じる。

 

なぜなら、ミュータブルオブジェクトを持つクラスは、通常ミュータブルオブジェクトの内容によって振る舞いが変わるから。※例外として、Collection系は参照の管理をするだけなのでchildによって振る舞いが変わらない。そのためCloneableである。

 

そこで、clone時にメンバ変数のミュータブルオブジェクトもcloneしたいが、final宣言されている場合は参照を置換できないため、正常にcloneできない。

 

 

つまりこういうクラスは通常Cloneableじゃないということ

class A implements Cloneable{
    public final ArrayList list = new ArrayList(); //cloneしたい
public A clone(){
A ret = super.clone();
ret.list = list.clone(); //コンパイルエラー、final宣言されているため代入できない
return ret;
} }