この質問はに関連しています なぜString.valueOf(null)はNullPointerExceptionをスローしますか?
次のスニペットを検討してください。
_public class StringValueOfNull {
public static void main(String[] args) {
String.valueOf(null);
// programmer intention is to invoke valueOf(Object), but instead
// code invokes valueOf(char[]) and throws NullPointerException
}
}
_
リンクされた質問への答えで説明したように、Javaのメソッドのオーバーロードは、上記の呼び出しを String.valueOf(char[])
に解決します。これにより、実行時にNullPointerException
が正しく生成されます。
Eclipseと_javac 1.6.0_17
_でコンパイルされた、これはスタックトレースです。
_Exception in thread "main" Java.lang.NullPointerException
at Java.lang.String.<init>(Unknown Source)
at Java.lang.String.valueOf(Unknown Source)
at StringValueOfNull.main(StringValueOfNull.Java:3)
_
上記のスタックトレースには、[〜#〜] key [〜#〜]情報がないことに注意してください。[~# 〜] not [〜#〜]はvalueOf
メソッドの完全なシグネチャを持ちます! String.valueOf(Unknown Source)
とだけ書かれています!
私が遭遇したほとんどの状況では、例外スタックトレースには常に、実際にスタックトレースにあるメソッドの完全なシグネチャがあります。もちろん、これはvery helpです。すぐに問題とスタックトレース(言うまでもなく構築するのにかなり費用がかかる)が提供される主な理由。
それでも、この場合、スタックトレースはまったく役に立ちません。プログラマーが問題を特定するのを助けることに悲惨なほど失敗しました。
現状では、プログラマーが上記のスニペットで問題を特定できる3つの方法を見ることができます。
String valueOf(char[] data)
が実際に選択されていることがプログラマーにすぐにわかります最後のオプションはおそらく最もアクセスしにくいですが、もちろん究極の答えです(プログラマーはオーバーロードルールを誤解する可能性がありますIDEはバグがあるかもしれませんが、バイトコードは常に(?)行われます)。
これは通常、不足しているデバッグ情報に関連しています。おそらくrt.jarクラスのデバッグ情報が含まれていない(JDKではなく)JREを使用している可能性があります。完全なJDKを使用してみてください。スタックトレースで適切な場所を取得できます。
Exception in thread "main" Java.lang.NullPointerException
at Java.lang.String.<init>(String.Java:177)
at Java.lang.String.valueOf(String.Java:2840)
at StringValueOfNull.main(StringValueOfNull.Java:3)
Antビルドを使用していて、javacコマンドでdebug属性がfalseに設定されている場合、これが発生する可能性があることに注意してください。
例:トレースセットで適切な場所が必要な場合debug = true Antビルドで、
<javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.Java">
<classpath refid="compile.classpath" />
</javac>
私は同じ問題を抱えていた、私はspringとApache antを継続的な統合に使用している。
エラーはbuild.xmlファイルにありました。
より正確なコンテンツを含む性別変更ログは次のとおりです。
エラーが発生したbuild.xml:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes">
<classpath refid="compile.classpath" />
</javac>
エラーなしのbuild.xml:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes" debug="true">
<classpath refid="compile.classpath" />
</javac>
構造内で私は勇気に欠けていましたdebug = "true"
Eclipseでコードを実行すると、次の出力が得られました。
public class Aloof {
public static void main(String[] args) {
String.valueOf(null);
}
}
Exception in thread "main" Java.lang.NullPointerException
at Java.lang.String.<init>(String.Java:177)
at Java.lang.String.valueOf(String.Java:2840)
at mysql.Aloof.main(Aloof.Java:19)
完全なソース(JDKから)を含めると、実際にString.Javaの177行目までデバッグできます。
Eclipseの場合:Preferences> Java> Installed JREs。チェック済みのエントリには、JDK内のパスが必要です(例:C:\ Program Files(x86)\ Java\jdk1.7.0_55\jre)。
これは、ソースにデバッグ(行)情報がない場合、またはVMがクラスのロード時にその情報を破棄するように指示されている場合に発生します。行番号があるため、VM設定ではなく、クラスString
にデバッグ情報がありません。