元の質問の背後にあるより重要な質問を公開したと思います。ゲッターとセッターの例外的なケースを防ぐために作業する必要がありますか?
答えはイエスです、あなたは些細な例外を避けるために働くべきです。
ここにあるのは、この例ではまったく動機付けられていない、事実上怠惰なインスタンス化です。
コンピュータプログラミングでは、レイジー初期化は、オブジェクトの作成、値の計算、またはその他の高価なプロセスを、最初に必要になるまで遅らせる戦術です。
この例では、次の2つの問題があります。
あなたの例はスレッドセーフではありません。nullのチェックは、2つのスレッドで同時に成功する(つまり、オブジェクトがnullであることがわかる)可能性があります。次に、インスタンス化により、2つの異なる文字列リストが作成されます。非決定論的な振る舞いが続きます。
この例では、インスタンス化を延期する正当な理由はありません。費用がかかる、または複雑な操作ではありません。これは、「些細な例外を回避するための作業」の意味です。サイクルを投資して、有用な(ただし空の)リストを作成し、遅延爆轟nullポインター例外をスローしないようにする価値があります。
外部コードに例外を課すときは、基本的に、開発者がそれを使って賢明なことを行う方法を知っていることを望んでいることを忘れないでください。また、あなたのような例外をキャッチして無視するためだけに、すべてを例外イーターでラップした方程式に3番目の開発者がいないことを望んでいます。
try {
// I don't understand why this throws an exception. Ignore.
t.getStrings();
} catch (Exception e) {
// Ignore and hope things are fine.
}
以下の例では、Null Objectパターンを使用して、例が設定されていないことを将来のコードに示しています。ただし、Null Objectは例外的ではないコードとして実行されるため、将来の開発者のワークフローにオーバーヘッドや影響を与えることはありません。
public class App {
static class Test {
// Empty list
public static final List<String> NULL_OBJECT = new ArrayList<String>();
private List<String> strings = NULL_OBJECT;
public synchronized List<String> getStrings() {
return strings;
}
public synchronized void setStrings(List<String> strings) {
this.strings = strings;
}
}
public static void main(String[] args) {
Test t = new Test();
List<String> s = t.getStrings();
if (s == Test.NULL_OBJECT) {
// Do whatever is appropriate without worrying about exception
// handling.
// A possible example below:
s = new ArrayList<String>();
t.setStrings(s);
}
// At this point, s is a useful reference and
// t is in a consistent state.
}
}