web-dev-qa-db-ja.com

nullPointerExceptionをデバッグする良い方法

Eclipseを使用し、Javaでプログラミングしています。時々、nullPointerExceptionに遭遇し、何時間も悩まされます。とにかくnullPointerExceptionsをよりよくデバッグし、変数値とnull Pointer Exceptionsを引き起こす他のものを把握する方法はありますか。

19
Noah Huppert

スタックトレースを見て、NullPointerExceptionがスローされる行番号を読み取ります。ほとんどの場合、行には次のようなメソッド呼び出しがあります。

_x.getValue()
_

xnullの場合、NullPointerExceptionを取得します。スタックトレースの一番上のメソッドがコードではない場合、コードに到達するまでスタックをさかのぼってトレースします。この場合、非常に多くの場合、nullパラメーターを好まないメソッドにnullを渡します。それを見つけて修正してください。

また、NullPointerExceptionをスローしている自分のものではないメソッドに遭遇したときは、ドキュメントをよく読んでください。たとえば、 String.replace(CharSequence target, CharSequence replacement) を見てください:

スロー

NullPointerException-targetまたはreplacementnullの場合。

それよりも明確ではありません!

以下に例を示します。

enter image description here

4行目を見ると、foo.bar()があります。これは、foonullであることを意味します。それは簡単です。別の例を見てみましょう。

enter image description here

コードに戻ると、s.replace(target, replacement)がスローされていることがわかります。 targetreplacementを検査する必要があります。デバッガーを接続しましょう:

enter image description here

あぁ! replacementnullです。 Eclipseでも同じことができます。例外がスローされたときにブレークポイントを設定し、それを使用してメソッドのパラメーターを検査します。私はここで原始的です。なぜなら、私が彼らが最初に苦労してそれをすることを学んだなら誰もがより良くなるだろうと本当に信じる考えの学校から来たからです。漏れやすい抽象化など。

24
jason
  1. デバッグ中にBreakPointsビューを使用して、nullポインターをキャプチャできます。

    ウィンドウ->ビューの表示->ブレークポイント

    ビューには、例外にブレークポイントを設定できる"J!"があります。 Java.lang.NullPointerExceptionを設定できます。したがって、NULLポインター例外がスローされると、どの変数がNULLを引き起こしているかを確認できます。

  2. 他にできることは、コーディング中にヌルポインターアクセスの可能性をキャプチャすることです。コース外では、この設定を使用してすべてのヌルポインターをキャプチャすることはできません。それでも便利ですが、Eclipseで次の設定を行います。

    設定-> Java-> Compiler-> Errors/warnings-> Null analysis

17
Jayamohan

NullPointerExceptionの問題を減らすには、いくつかの方法があります。

  1. @ Nullableアノテーション を使用します。

  2. コンストラクターとセッターでnullの引数の値をテストします(単純な古いJavaコード)のセッターを避けます。これを頻繁に行うと、(Eclipse)ソースコードを作成できます。これは「フェイルファスト」と呼ばれ、値がコードでさらに使用されているとき、たとえばフィールドに保存した後に例外がスローされるのを待ちません。

  3. 行ごとに最小限の操作(例:1または2)を実行するようにしてください。そうでない場合は、単一行の式のどこでNullPointerExceptionが発生したかを調べる必要があります。

  4. 状態を示すためにフィールドでnullを使用しないでください。代わりに、例えば_enum State_。例えば。後でnullをチェックするのを忘れやすいので、if (socket == null) { // not connected }をしないでください。明示的な状態を忘れることはそれほど簡単ではありません。

  5. 明示的に必要な場合を除き、ローカル変数をnullに初期化しないでください。実際、スコープと例外を正しく処理すれば、ほとんどの変数finalをマークできるはずです。デフォルトのprintStacktrace()メソッドをthrow new IllegalStateException("Unhandled program state", e)に置き換えると、コードブロックの出口点と見なされるため、役立ちます。

多くのプログラミングを行うと、NullPointerExceptionsの数が減少することがわかります。

4
Maarten Bodewes