-
08-07-2019 - |
質問
Javaには短絡評価があると思っていましたが、この行はまだnullポインター例外をスローしています:
if( (perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey())) ) {
この場合、 perfectAgent
は null
なので、式全体が false
を返すようにしたいのですが、これでアプリがクラッシュしますNullPointerExceptionのある行。
編集、一般的な応答:
perfectAgent
は null
であるため、&&
の右側には何も実行するべきではありません。真であります。さらに重要なのは、 perfectAgent
に有効な参照が含まれていない(nullおよびall)ため、 perfectAgent.getAddress()
を実行できないことです。別のステートメントでヌルをチェックする必要がないように、短絡評価を使用しようとしています。これにより、ロジックがより雑になります。
EDIT 2(または、私はばかです): ええ、人生の多くのことのように、あなたはあなたがバカだと世界に告げた直後に答えを見つけます。この場合、Eclipseの自動ビルドを他の何かをしている間にオフにして、オンに戻さなかったため、ソースと一致しないクラスファイルをデバッグしていました。
解決
高度なデバッグレッスン#1:
一見不可能なエラー(Javaに関する知識と矛盾するエラーなど)が発生した場合は、次の手順を実行します。
-
信頼できるテキストブック(または関連する標準)を参照して、理解に欠陥がないことを確認してください。 (この場合、あなたの理解は正しかったので、まともな教科書ならすぐにこれを確認できます。)
-
不可能なエラーを引き起こす可能性のある、愚かなことをすべて確認してください。ファイルを保存しない、完全なビルドを行わない、アプリケーションの古い/古いバージョンを実行する、間違ったディレクトリにいるなどのようなもの。
要約すると、もう少し自分自身を疑うことを学んでください。
他のヒント
perfectAgent
が本当にnullの場合、そのコードは例外をスローしません(少なくとも奇妙なスレッド処理が行われていないと仮定して、式の途中でnullからnullまで)。それを実証する短いが完全なプログラムを作成できるなら、私はまったくショックを受けます。
そうです、あなたの直感は正しいです-これは問題ではないはずです。原因を他の場所で調べてください。 perfectAgent
は実際にはnullではないと、そのコードで例外を引き起こす可能性のある他の状況に遭遇していると強く思います。
そのコードの一部を、短いが完全な例に抽出することをお勧めします-可能であれば、比meta的な帽子を食べます。そうでない場合は、抽出を試みているときに問題を見つけることができます。
perfectAgent
が本当に nullであると思われる理由は何ですか?このコードをその前に挿入してみてください:
if (perfectAgent == null)
{
System.out.println("Yup, it's null");
}
別の非常に非常にスリムな可能性は、JITバグに遭遇したということです-しかし、私はそれを非常に疑います。
Javaには短絡評価があります 。 entry
が null
であるため、 entry.getKey()
が NullPointerException
を引き起こしている可能性があります。別の可能性は、 getAddress()
が null
を返すか、どこかで NullPointerException
が発生することです(単純な returnよりも複雑な場合
ステートメント)。
編集:あなたがこれを主張するところに編集が表示されます:
さらに言えば、
perfectAgent.getAddress()
を実行することは不可能です...
しかし、 perfectAgent.getAddress()
が正常に実行され、戻る null
の場合はどうなりますか?意味を確認してください...
perfectAgent
がnullでないことを確認します。したがって、1つ以上の perfectAgent.getAddress()
または entry
または entry。 getKey()
はnullでなければなりません。または、getAddress()またはgetKey()が実装でNPEにヒットしています。
この種のことをデバッグするには、最初にスタックトレースを見て、場所を特定します。これにより、getAddress()、getKey()、またはそれらを呼び出す貼り付けられたコードスニペットで発生しているかどうかがわかります。次に、このスニペットにある場合、テストするifの前にコードを追加して、どれがヌルであるかをテストします。古き良きSystem.err.println()またはアサーション。 (アサーションを使用する場合は、javaコマンドの-enableassertionsフラグを使用してアサーションを有効にしてください。)
更新:それで、私の解釈が間違っていたことが判明しました...問題は2つの矛盾する事実を示しました(この行にはNPEがありましたが、短絡が発生するはずでした)そして私は自動的に最初の事実は真であり、2番目の事実は、Eclipseの自動ビルドを完全にオフにしたことによるまったく別の問題であったときに、偽であると仮定しました。ああ!何か「不可能」をデバッグする際に根本的に懐疑的であることが役立ちます。
perfectAgent以外にもnullの可能性がある3つの参照があります:
- perfectAgent.getAddress()
- エントリ
- entry.getKey()
ステートメントを分割するか、デバッガーで実行します。
大きなミステリー。コード行をコピーし、 perfectAgent == null
、 entry == null
、 entry.getKey()== null
および組み合わせでテストしましたそれらのうち:私のテストベッドにはNPEがありません(Java 1.6)。
どのような迷惑なバグであっても、短絡評価と関係があるとは思いません。 NPEを引き起こすこの行の場合、私が言える限り、perfectAgentはnullではありません。幸運を祈ります-キャッチしたらバグを見せてください:)
次のようにコードをフォーマットしてみてください:
if(
(perfectAgent != null)
&& (
perfectAgent.getAddress()
.equals(
entry.getKey()
)
)
) {
これにより、スタックトレースの行エントリが改善されます。