[解決済み] String.valueOf(null)がNullPointerExceptionをスローするのはなぜですか?
質問
ドキュメントによると
String.valueOf(Object obj)
が返します。
もし引数が
null
と等しい文字列を返します。"null"
それ以外の場合はobj.toString()
の値が返されます。
しかし、私はこれを行うしようとすると、なぜです。
System.out.println("String.valueOf(null) = " + String.valueOf(null));
を実行すると、代わりにNPEを投げるのですか?(信じられないなら自分で試してみてください!)
スレッド "main" java.lang.NullPointerException で例外が発生しました。 at java.lang.String.(ソース不明) at java.lang.String.valueOf(提供元不明)
どうしてこんなことが起こるのでしょうか?ドキュメントが嘘をついているのでしょうか?これはJavaの大きなバグなのでしょうか?
どのように解決するのですか?
この問題は
String.valueOf
メソッドが
オーバーロード
:
Java 仕様言語では、このような場合、以下のように義務付けられています。 最も具体的なオーバーロード が選択されます。
JLS 15.12.2.5 最も具体的な方法を選択する
複数のメンバメソッドがメソッド呼び出しにアクセス可能かつ適用可能である場合、実行時メソッドディスパッチ用の記述子を提供するために1つを選択することが必要です。Javaプログラミング言語では 最も具体的な メソッドが選択されます。
A
char[]
は
Object
であり、すべてではありませんが
Object
は
char[]
. したがって
char[]
は
より具体的
よりも
Object
であり、Java 言語で指定されているように
String.valueOf(char[])
のオーバーロードがこの場合選択されます。
String.valueOf(char[])
は、配列が非表示であることを期待します。
null
であることを期待し、また
null
が指定されている場合は
NullPointerException
.
簡単な修正は
null
に明示的にキャストすることです。
Object
を以下のように変更します。
System.out.println(String.valueOf((Object) null));
// prints "null"
関連する質問
物語のモラル
重要なものがいくつかあります。
-
Effective Java 第2版、項目41:オーバーロードを賢く使う
- オーバーロードが可能だからといって、毎回オーバーロードする必要はありません。
- 混乱を招く可能性がある (特にメソッドが全く異なることを行う場合)
-
優れた IDE を使用すると、コンパイル時にどのオーバーロードが選択されたかを確認できます。
-
Eclipseでは、上記の式にマウスを乗せると
確かに
と表示されます。
valueOf(char[])
のオーバーロードが選択されています!
-
Eclipseでは、上記の式にマウスを乗せると
確かに
と表示されます。
-
時には、明示的にキャストしたい
null
を明示的にキャストしたい場合があります (後述する例)。
こちらもご覧ください
キャストについて
null
少なくとも二つの状況において、明示的に
null
を特定の参照型にキャストすることが必要な状況が少なくとも二つあります。
- オーバーロードを選択する場合(上記の例で与えられたように)
-
以下のように
null
を vararg パラメータへの単一引数として与える。
後者の簡単な例として、以下のようなものがあります。
static void vararg(Object... os) {
System.out.println(os.length);
}
とすれば、以下のようになります。
vararg(null, null, null); // prints "3"
vararg(null, null); // prints "2"
vararg(null); // throws NullPointerException!
vararg((Object) null); // prints "1"
こちらもご覧ください
- Java言語ガイド/引数 - を読んで、どのように実装されているかを理解しましょう。
関連する質問
関連
-
JQuery DataTable 详解
-
[解決済み] この2回(1927年)を引き算すると、なぜおかしな結果になるのでしょうか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] JavaScriptで空文字列/未定義文字列/null文字列をチェックするにはどうすればよいですか?
-
[解決済み] JavaScriptでNULL、未定義、空白の変数をチェックする標準的な関数はありますか?
-
[解決済み] 変数が「未定義」または「NULL」であるかどうかを判断するにはどうすればよいですか?
-
[解決済み] Javaはパラメータのデフォルト値をサポートしていますか?
-
[解決済み] instanceofを呼び出す前にnullチェックは必要ですか?
-
[解決済み】なぜJavaの+=, -=, *=, /=複合代入演算子はキャスティングを必要としないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
java の例外が発生しました java
-
ファインバグタイプ
-
Eclipseでプロジェクトエクスプローラービューとパッケージエクスプローラービューを使う
-
Spring boot runs with Error creating bean with name 'entityManagerFactory' defined in class path resource
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
リソースの読み込みに失敗しました。サーバーはステータス500(内部サーバーエラー)で応答しました。
-
javaコンパイル時のエラー:不正な文字 '\ufeff' に対する解決策です。
-
ブラウザでの大容量ファイルスライスアップロード(Javaサーバサイド実装)
-
[解決済み] ポリモーフィズム vs オーバーライド vs オーバーローディング
-
[解決済み】switchでnullを使用する方法