この質問はほとんど「死ぬほど答えられた」ものですが、役に立つポイントが他にもいくつかあると思います。
try / catch
非例外的な制御フローに使用するのは悪いスタイルです (Java では)。(「非例外的」が何を意味するかについてはよく議論されますが、それは別のトピックです。)
それが悪いスタイルである理由の1 つは、通常の制御フロー ステートメントよりも桁違いにコストがかかるtry / catch
ことです1。実際の違いはプログラムとプラットフォームによって異なりますが、1000 倍以上の費用がかかると思います。特に、例外オブジェクトを作成すると、スタック トレースがキャプチャされ、スタック上の各フレームに関する情報が検索およびコピーされます。スタックが深ければ深いほど、コピーする必要があるものは多くなります。
それが悪いスタイルであるもう 1 つの理由は、コードが読みにくいことです。
1 - 最近のバージョンの Java の JIT は例外処理を最適化して、場合によってはオーバーヘッドを大幅に削減できます。ただし、これらの最適化はデフォルトでは有効になっていません。
例を書いた方法にも問題があります。
Exception
他のチェックされていない例外を誤ってキャッチする可能性があるため、キャッチは非常に悪い習慣です。たとえば、呼び出しの周りでそれを行うと、潜在的なs ...raw.substring(1)
もキャッチされ、バグが隠されます。StringIndexOutOfBoundsException
あなたの例がやろうとしていることは、(おそらく)null
文字列を扱う際の練習不足の結果です。一般的な原則として、文字列の使用を最小限に抑え、null
(意図的な) 拡散を制限するように努める必要があります。可能であれば、null
「値なし」を意味するのではなく、空の文字列を使用してください。また、文字列を渡したり返したりする必要がある場合はnull
、メソッドの javadoc で明確に文書化してください。メソッドが呼び出されるnull
べきではないときに呼び出される場合...それはバグです。例外をスローさせます。(この例では) を返すことによってバグを補おうとしないでくださいnull
。
私の質問は、null
値だけでなく、より一般的なものでした。
...そして、私の答えのポイントのほとんどは、null
価値観に関するものではありません!
ただし、ときどき null 値や、例外を生成する可能性のあるその他の値を許可し、それらを無視したい場合が多いことに注意してください。これは、たとえば、どこかからキー/ペアの値を読み取り、それらを上記の tryTrim() のようなメソッドに渡す場合です。
はい、null
値が期待される状況があり、それらに対処する必要があります。
しかし、私tryTrim()
が行っていることは (通常) に対処するための間違った方法であると主張しnull
ます。次の 3 つのコードを比較します。
// Version 1
String param = httpRequest.getParameter("foo");
String trimmed = tryTrim(param);
if (trimmed == null) {
// deal with case of 'foo' parameter absent
} else {
// deal with case of 'foo' parameter present
}
// Version 2
String param = httpRequest.getParameter("foo");
if (param == null) {
// deal with case of 'foo' parameter absent
} else {
String trimmed = param.trim();
// deal with case of 'foo' parameter present
}
// Version 3
String param = httpRequest.getParameter("foo");
if (param == null) {
// treat missing and empty parameters the same
param = "";
}
String trimmed = param.trim();
最終的にはnull
、通常の文字列とは異なる方法で処理する必要があり、通常はできるだけ早くこれを行うことをお勧めします。null
がその原点からさらに伝播できるようになればなるほど、プログラマーは値が可能性であることを忘れ、null
null 以外の値を想定するバグのあるコードを書く可能性が高くなります。また、HTTP 要求パラメーターが欠落している可能性があること (つまりparam == null
) を忘れることは、これが発生する典型的なケースです。
tryTrim()
それが本質的に悪いと言っているのではありません。しかし、このようなメソッドを作成する必要性を感じているという事実は、おそらくnull 処理が理想的ではないことを示しています。
最後に、API で「値がない」ことをモデル化する方法は他にもあります。これらには以下が含まれます:
- セッターとコンストラクターで予期
null
しないことをテストし、例外をスローするか、別の値に置き換えます。
- メソッドを追加し、結果が の場合に
is<Field>Set
例外をスローします。get<Field>
null
- Null オブジェクト パターンを使用します。
null
文字列、コレクション、または配列の代わりに、空の文字列、空のコレクション、長さゼロの配列などを使用します1。
- を使用して
Optional
います。
1 - 「nullity」を表す型のインスタンスが 1 つだけであるとは限らないため、これは Null オブジェクト パターンとは異なります。しかし、この 2 つのアイデアを組み合わせることができます。