Effective Java 第 2 版:第 2 章 オブジェクトの生成と消滅 項目 5
不必要なオブジェクトの生成を避ける
リソースを効率よく使うためには、以下のような不必要なオブジェクトの生成はできるだけ避けたいという話。
- 不変クラスを毎回
new
- メソッドが呼び出されるごとの高コストなオブジェクトの生成
- アダプターの複数個生成
- 意図しないオートボクシング
不変クラスを毎回 new
不変クラスの例として String
で考えるとわかりやすい。
String str = new String("Hogeeee");
は、ループ内などで何度も実行されると、その回数分だけインスタンスを生成してしまう。
その代わりに、String str = "Hogeeee";
のように文字列リテラルを使えば、何度実行しても 1 個のインスタンスを共有できる。
また、static ファクトリーは不必要なインスタンスを生成しないことがほとんど。
メソッドが呼び出されるごとの高コストなオブジェクトの生成
メソッドの中に生成コストの大きいインスタンス(例として Calender
, TimeZone
が挙げられている)を生成する処理があると、 そのメソッドが呼び出されるたびにインスタンスの生成が起き、コストがかかる。
その代わりに、以下のように static 初期化子を使って、クラス初期化時点でインスタンスを生成するようにしておくとよい。
public class Hoge {
static {
// クラスのインスタンス生成時に一度だけ初期化される
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("JST"));
// ...その他の重い初期化
}
public void doSomething() {
// ...
}
}
アダプターの複数個生成
Map#keySet
で返される Set
ビューは Map
の内部に対するインタフェースの役割を果たし、処理は内部へ委譲しているアダプターといえる。
この場合、一つの Set
ビューから内部を変更すると、他の Set
ビューから見てもその変更が反映されている。
つまり、どのインスタンスから内部を見ても同じ状態であるため、複数個インスタンスを生成する必要はない。
意図しないオートボクシング
オートボクシングとは、基本データ型から基本データ型のラッパークラスに自動で変換される Java の機能である。
例えば、以下のコードでは int
型の値が Integer
クラスのオブジェクトに自動で変換される。
Integer i = 10;
これは便利な機能ではあるが、何度も実行されたとき、コストが大きくなってしまう。 そのため、不必要な場面でオートボクシングが起きないように気を付ける必要がある。