Java はどのポインタが null であるかを教えてくれないのはなぜですか?
-
19-09-2019 - |
質問
私はいつも疑問に思っていましたが、なぜ JVM はそれを教えてくれないのでしょうか。 どれの ポインター (より正確には、どの変数) が null の場合、 NullPointerException
投げられる。
問題のある行には、エラーの原因となる可能性のある多数の変数が含まれていることが多いため、行番号は十分具体的ではありません。
これらの例外メッセージをより便利にするコンパイラまたは JVM フラグはありますか?
解決
利用できる名前がないとき間接参照は常に起こるためです。値は、オペランドスタック上にロードされ、そして、それを間接参照JREオペコードのいずれかに渡されます。しかし、オペランドスタックはNULL値に関連付ける名前がありません。それが持っているすべては「NULL」です。いくつかの巧妙な実行時のトラッキングコードを使用すると、名前を導出することができるが、それは限られた値とのオーバーヘッドを追加します。
このため、nullポインタ例外のための余分な情報になります何のJREオプションがありません。
この例では、参照は、ローカル変数名にマップローカルスロット1に格納されています。しかし、間接参照はスタック上に「NULL」値を見INVOKEVIRTUAL命令、で行われ、その後、例外をスローします:
15 aload_1
16 invokevirtual #5
等しく有効デリファレンス続く配列負荷することができるが、この場合には「NULL」値が、別の値のオフだけインデックスにマップする名前が存在しないであろう。
76 aload 5
78 iconst_0
79 aaload
80 invokevirtual #5
あなたはどちらか、各命令に静的に名前を割り当てることができない - この例では、バイトコードの多くを生成しますが、逆参照命令がOBJAまたはobjBのいずれかを受け取ることになりますし、あなたが報告し、これを動的に追跡する必要があるだろうことがわかります右のいずれか、両方の変数が同じ間接参照命令に流れてます:
(myflag ? objA : objB).toString()
他のヒント
あなたは、コードをJITたら、それだけでネイティブポインタ数学だし、ネイティブコードのいずれかのポインタがnullの場合、それは例外をスローします。これは、元の変数にそのアセンブリを逆に壊滅的なパフォーマンスへの影響を有し、JITを考慮すると、様々なレベルに生成されたコードを最適化し、多くの場合も可能ではないだろう。
、または、あなたはかなり簡単にNULLである参照把握することができます。
もし
違反行には、エラーを引き起こす可能性のある多数の変数が含まれることが多いため、行番号は十分に具体的ではありません。
それから私はこう提案します:
- その行を複数の行に分割し、可能なものを割り当てます。
NullPointerException
-一時変数に値を生成します。 - デバッガーを使用して、問題の原因となっているメソッドが見つかるまで各メソッド呼び出しをステップ実行します。
これは、残念ながらJavaが動作するだけの方法です。
これは、「あなた」のコードは、単に
のようなスニペットを追加している場合if (foo == null) {
throw new NullPointerException("foo == null");
}
右のfooを割り当てた後。 fooがパラメータである場合、メソッド本体の開始時にすぐにチェックして、代わりにIllegalArgumentExceptionをスローします。
これは、あなたが問題を明確に役立つはずです。
あなたはEclipseでnullポインタ例外にブレークポイントを追加することができます。