132

ドキュメントによると、メソッドは次をString.valueOf(Object obj)返します。

引数が、の場合、;nullに等しい文字列。"null"それ以外の場合は、の値obj.toString()が返されます。

しかし、私がこれをやろうとするとどうしてですか?

System.out.println("String.valueOf(null) = " + String.valueOf(null));

代わりにNPEをスローしますか?(信じられない場合は、自分で試してみてください!)

    スレッド「メイン」の例外java.lang.NullPointerException
    java.lang.String。(不明なソース)で
    java.lang.String.valueOf(不明なソース)で

どうしてこれが起こっているのですか?ドキュメントは私に嘘をついていますか?これはJavaの主要なバグですか?

4

4 に答える 4

210

問題は、String.valueOfメソッドがオーバーロードされていることです:

Java仕様言語では、このような場合、最も具体的なオーバーロードを選択することが義務付けられています。

JLS15.12.2.5最も具体的な方法の選択

複数のメンバーメソッドがアクセス可能であり、メソッド呼び出しに適用できる場合は、実行時メソッドディスパッチの記述子を提供するために1つを選択する必要があります。Javaプログラミング言語は、最も具体的な方法が選択されるという規則を使用します。

Achar[] は-です Objectが、すべてObject ではあり char[]ません-a 。したがって、はよりchar[]具体的Objectあり、Java言語で指定されているようString.valueOf(char[])に、この場合はオーバーロードが選択されます。

String.valueOf(char[])配列が非nullであると想定しnull、この場合はであるため、をスローしNullPointerExceptionます。

簡単な「修正」は、次のようにnull明示的にキャストすることです。Object

System.out.println(String.valueOf((Object) null));
// prints "null"

関連する質問


この話の教訓

重要なものがいくつかあります。

  • 効果的なJava2ndEdition、アイテム41:オーバーロードを慎重に使用する
    • あなたが過負荷になることができるという理由だけで、あなたが毎回すべきであるという意味ではありません
    • それらは混乱を引き起こす可能性があります(特にメソッドが大きく異なることを行う場合)
  • 優れたIDEを使用すると、コンパイル時にどのオーバーロードが選択されているかを確認できます
    • Eclipseを使用すると、上記の式にマウスを合わせると、実際valueOf(char[])オーバーロードが選択されていることがわかります。
  • 明示的にキャストしたい場合がありますnull(以下の例)

も参照してください


キャスティングについてnull

null特定の参照型に明示的にキャストする必要がある状況は少なくとも2つあります。

  • オーバーロードを選択するには(上記の例で示したように)
  • nullvarargパラメータに単一の引数として与える

後者の簡単な例は次のとおりです。

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"

も参照してください

関連する質問

于 2010-06-28T11:21:22.537 に答える
18

問題は、あなたが呼んString.valueOf(char[])でいるのであって、ではない String.valueOf(Object)ということです。

この理由は、Javaは、提供されたパラメーターで機能するオーバーロードされたメソッドの最も具体的なバージョンを常に選択するためです。nullはパラメータの有効な値ですが、Objectパラメータの有効な値でもありchar[]ます。

JavaにObjectバージョンを使用させるにnullは、変数を介して渡すか、オブジェクトへの明示的なキャストを指定します。

Object o = null;
System.out.println("String.valueOf(null) = " + String.valueOf(o));
// or
System.out.println("String.valueOf(null) = " + String.valueOf((Object) null));
于 2010-06-28T11:26:52.367 に答える
4

2003年にこの方法で番号4867608のバグが報告されましたが、この説明で「修正されない」として解決されました。

互換性の制約により、これを変更することはできません。最終的に呼び出されるのはpublicstaticString valueOf(char data [])メソッドであり、null引数の「null」の置き換えについては言及されていないことに注意してください。

@###。###2003-05-23

于 2012-11-01T18:56:15.527 に答える
0

String.valueOf(null: Any)Scalaで使用します。

于 2020-07-01T15:20:34.767 に答える