パンくず
Effective Java
必要な場合には、防衛的にコピーする
概要
必要な場合には、防衛的にコピーする
詳細
クラスの内部を変更されたくない場合は、防衛的コピーによって
参照を渡さずに値をコピーして渡すこと。
これにより、外部から意図せぬ変更をされることを防ぎます。
また、クラス内から外部に値を返却する際も
防衛的コピーを行った値を返却すること。
上記は副作用の無いクラスを作成する上で重要な要素であるが
コピーのコストが大きい場合は、クラスの利用者が信頼出来る相手に限られている場合は
ドキュメンテーションを残した上で防衛的コピーを行わないという判断も可能。
サンプルコード
package effective.creation.chapter6; public class SampleNo39 { public static class InnerHoge { private String name; private int age; public InnerHoge name(String name) { this.name = name; return this; } public InnerHoge age(int age) { this.age = age; return this; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "InnerHoge [name=" + name + ", age=" + age + "]"; } } public static class HogeBefore { private final InnerHoge hoge; public HogeBefore(InnerHoge hoge) { this.hoge = hoge; } public InnerHoge hoge() { return hoge; } @Override public String toString() { return "HogeBefore [hoge=" + hoge + "]"; } } public static class HogeAfter { private final InnerHoge hoge; public HogeAfter(InnerHoge hoge) { this.hoge = new InnerHoge().name(hoge.name).age(hoge.age); } public InnerHoge hoge() { return new InnerHoge().name(hoge.name).age(hoge.age); } @Override public String toString() { return "HogeBefore [hoge=" + hoge + "]"; } } public static void main(String[] args) { InnerHoge hoge = new InnerHoge().name("hoge").age(20); HogeBefore hogeBefore = new HogeBefore(hoge); HogeAfter hogeAfter = new HogeAfter(hoge); hoge.name("hage"); hoge.age(30); System.out.println(hogeBefore); System.out.println(hogeAfter); hogeBefore.hoge().name("hige"); hogeAfter.hoge().name("hige"); System.out.println(hogeBefore); System.out.println(hogeAfter); } }