問題

私は NullPointerException を避けるために多くのobject != nullを使用します。

これには良い選択肢がありますか?

例えば:

 if (someobject != null) {
    someobject.doCalc();
}
 

これは、オブジェクトが null かどうかわからない場合、NullPointerException を避けます。

受け入れられた答えは古くなっている可能性があることに注意してください。より新しいアプローチについては、 https://stackoverflow.com/a/2386013/12943 を参照してください。

  ベストアンサー

これは、ジュニアから中間の開発者がある時点で直面する傾向があるという合理的に一般的な問題のように聞こえます。彼らは、彼らが参加している契約を知らないか、または信頼していないか、nullを防御する。さらに、独自のコードを書くとき、彼らは何かを示すためにヌルを返すことに頼る傾向があり、呼び出し元がヌルをチェックする必要があります。

これを別の方法で言うと、nullチェックが発生する2つのインスタンスがあります。

  1. nullは契約に関して有効な応答です。

  2. それは有効な応答ではありません。

(2)簡単です。 assertステートメント(アサーション)を使用するか、失敗を許可する(たとえば、 NullPointerException )。アサーションは、1.4で追加された高解度なJava機能です。構文は次のとおりです。

 assert <condition>
 

または

 assert <condition> : <object>
 

<condition>はブール式で、<object>toString()メソッドの出力がエラーに含まれるオブジェクトです。

条件が真でない場合、assertステートメントはError(AssertionError)をスローします。デフォルトでは、Javaはアサーションを無視します。オプション-eaをJVMに渡してアサーションを有効にできます。個々のクラスとパッケージのアサーションを有効または無効にすることができます。つまり、アサーションの開発とテスト中にアサーションを使用してコードを検証し、プロダクション環境で無効にすることがで

この場合、アサーションを使用しないでください。これは、コードが失敗するためです。これは、アサーションを使用するとどうなりますか。唯一の違いは、アサーションでは、より意味のある方法で、おそらく余分な情報を使用して、それがなぜ起こったのかを理解するのに役立つかもしれないということです。

(1)は少し難しいです。あなたが呼び出しているコードを制御できない場合、あなたは立ち往生しています。 nullが有効な応答である場合は、それを確認する必要があります。

しかし、あなたが制御するコードであれば(これはしばしばそうです)、それは別の話です。応答としてnullを使用しないでください。コレクションを返すメソッドを使用すると、簡単です:NULLの代わりに空のコレクション(または配列)を返します。

非コレクションでは難しいかもしれません。これを例として考えてみましょう。これらのインタフェースがある場合:

 public interface Action {
  void doSomething();
}

public interface Parser {
  Action findAction(String userInput);
}
 

Parserは生のユーザー入力を受け取り、何かを見つける場合、おそらく何かのコマンドラインインターフェイスを実装している場合です。適切なアクションがない場合はnullを返すという契約をするかもしれません。それはあなたが話しているヌルチェックを導きます。

別の解決策は、決してnullを返さず、代わりに Nullオブジェクトパターンを使用することです。

 public class MyParser implements Parser {
  private static Action DO_NOTHING = new Action() {
    public void doSomething() { /* do nothing */ }
  };

  public Action findAction(String userInput) {
    // ...
    if ( /* we can't find any actions */ ) {
      return DO_NOTHING;
    }
  }
}
 

比較:

 Parser parser = ParserFactory.getParser();
if (parser == null) {
  // now what?
  // this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
  // do nothing
} else {
  action.doSomething();
}
 

 ParserFactory.getParser().findAction(someInput).doSomething();
 

より簡潔なコードにつながるので、はるかに優れたデザインです。

つまり、おそらくfindAction()メソッドが意味のあるエラーメッセージでExceptionをスローすることは完全に適切です。この場合、特にユーザー入力に依存しています。説明のない単純なNullPointerExceptionで爆破する呼び出しメソッドよりもfindActionメソッドが例外をスローする方がはるかに良いでしょう。

 try {
    ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
    userConsole.err(anfe.getMessage());
}
 

または、try/catchメカニズムがあまりにも醜いと思う場合は、デフォルトのアクションはユーザーにフィードバックを提供する必要があります。

 public Action findAction(final String userInput) {
    /* Code to return requested Action if found */
    return new Action() {
        public void doSomething() {
            userConsole.err("Action not found: " + userInput);
        }
    }
}
 

  同じタグがついた質問を見る

javaobjectnullpointerexceptionnull