これまでのcloneの実装だと、浅いコピーになるため、正しい深いコピーの実装をする。
Cloneable (Java Platform SE 6)
Javaのcloneメソッドの正しい実装方法 - Qiita
厳密には、Cloneableにはcloneメソッドが含まれない模様。
(なのでタイトルはおかしいが、実質そういうような感じなので。)
SubObjectを追加し、
class SubObject{
int data;
public void setData(int data) {
this.data = data;
}
@Override
public String toString(){
String retStr = "SubObject[data = " + data + "]";
return retStr;
}
}
新たにint型のdataを持つ。
class CustomObject implements Cloneable{
String str;
int value;
SubObject subObj;
public void setStr(String str) {
this.str = str;
}
public void setValue(int value) {
this.value = value;
}
public void setSubObj(SubObject subObj){
this.subObj = subObj;
}
public void setData(int data){
this.subObj.data = data;
}
@Override
public String toString(){
String retStr = "CustomObject[str = " + str + ", " + "value = " + value + ", subObj.data = " + subObj.data + "]";
return retStr;
}
@Override
public Object clone(){
try{
return (CustomObject)super.clone();
}
catch (CloneNotSupportedException e){
throw new InternalError(e.getMessage());
}
}
}
これをCustomObjectのメンバに追加。
class MainClass {
public static void main(String[] args) {
CustomObject obj1 = new CustomObject();
obj1.setStr("ABC");
obj1.setValue(123);
SubObject subObj1 = new SubObject();
subObj1.setData(100);
obj1.setSubObj(subObj1);
System.out.println("obj1.toString() = " + obj1.toString());
CustomObject obj2;
obj2 = (CustomObject)obj1.clone();
obj2.setStr("XYZ");
obj2.setValue(789);
obj2.setData(200);
System.out.println("obj2.toString() = " + obj2.toString());
System.out.println("obj1.toString() = " + obj1.toString());
}
}
これでクローンをすると、
obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 100]
obj2.toString() = CustomObject[str = XYZ, value = 789, subObj.data = 200]
obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 200]
subObjのほうは、クローンしても参照をコピーしてるので、obj2の変更の影響がobj1に出てしまう。
Cloneableでcloneを実装し、
自身をクローンした後、subObj分もクローンしてもらって、それを返すようにする。
obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 100]
obj2.toString() = CustomObject[str = XYZ, value = 789, subObj.data = 200]
obj1.toString() = CustomObject[str = ABC, value = 123, subObj.data = 100]
obj2の変更が、obj1には影響しないようになった。
Sample/java/Cloneable/clone/src/Cloneable at master · bg1bgst333/Sample · GitHub