2016-09-08 15 views
0

Javaの場合、私が書いた場合:
System.out.println((String) null);、私は"null"を得ます。Javaがnull参照をString "null"にキャストするのはなぜですか?

これは奇妙なようです。デザイナーがこのアプローチを選んだ理由を知っている人はいますか?これは、「何もないものを創造する」ケースであると私は思う。私はJLS entry on cast operatorsを読んで、それは言う:

キャスト式のタイプは、名前が括弧内に表示されるタイプにキャプチャ変換(§5.1.10)を適用した結果です。
キャスト式の結果は、変数ではなく、オペランド式の結果が変数であっても値です。 entry on capture conversionへジャンプ

、私は一般的なタイプのために定義されたキャプチャの変換を参照してください、しかし、エントリが追加されます:パラメータ化された型以外の任意の型(§4.5)の

キャプチャ変換が恒等変換として機能(5.1.1)。

大丈夫です! entry on identity conversionにあり、これがあります:

どのタイプから同じタイプへの変換も許可されています。この場合

、タイプがStringですが、変換する事がnullであり、それは混乱し、私を残しました。しかし、Javaが実際に(String) nullの文字列変換を使用していることが判明しました。 JLS entry on String conversionは言う:

任意のタイプは、参照がnullの場合は...文字列変換によって
を文字列型に変換することができる、それが文字列に変換され、「ヌル」(4つのASCII文字N、U、 l、l)。

HashMap map = new HashMap(); 
System.out.println((String)map.get("something")); 

プログラムプリント"null":これが提起

一つの問題は、このです。エントリがnullでHashMapの文字列がnull(4つのASCII文字 'n'、 'u'、 'l'、 'l')であるため、今では、誰かが、Javaがraw typesの使用を失望させ、タイプHashMapをパラメータ化する必要があると言うでしょうが、それは解決策ですか?

+0

代わりに何をすると思われますか? –

+0

おそらく 'NullPointerException'をスローする – Nayuki

+0

誰もが' System.out.println'を使ってデバッグしようとしています。デバッグに使用される主要なツールが例外を投げた場合、それはうまくいかないでしょう。実用的なものをあまり驚くべきものにするのは実用的な選択であり、完全に論理的なものではありません。 –

答えて

-1

あなたはこれを考えすぎています。 Javaは(値)nullを(文字列)"null"にキャストしていません。正解は、これは単にPrintStream.println(String)メソッドの明示的な動作に過ぎないことです。

文字列を出力してから終了します。このメソッドは、print(String)を呼び出すのと同様に動作し、次にprintln()を呼び出します。

次はPrintStream.print(String)が言いたいこと相談:

は、文字列を出力します。引数がnullの場合は、文字列"null"が出力されます。それ以外の場合、文字列の文字はプラットフォームのデフォルト文字エンコーディングに従ってバイトに変換され、これらのバイトはwrite(int)メソッドとまったく同じ方法で記述されます。

は(System.outのタイプPrintStreamで、注意してください。)

-1
HashMap map = new HashMap(); 
System.out.println((String)map.get("something")); 

プログラム印刷"null"。 のエントリがnullであったのに対して、HashMapの文字列が "null"の値 (4つのASCII文字 'n'、 'u'、 'l'、 'l')を持っているため、

ありnull"null"の違いはまだだ、あなたはちょうどあなたがSystem.out.printlnでそれらをプリントアウトしたときにことを見ることができません。彼らは、異なる値だ、と彼らは異なり、比較ん:

HashMap map = new HashMap(); 
map.put("foo", "null"); 
String something = (String) map.get("something"); 
String foo = (String) map.get("foo"); 
System.out.println(something == null); // true 
System.out.println(foo == null); // false 
System.out.println("null".equals(something)); // false 
System.out.println("null".equals(foo)); // true 
-1

それは鋳造とは何の関係もしませんが、印刷して:あなたはStringにnullをキャストした場合、それはまだnullです:

String s=(String)null; 
if (s==null) 
{ 
    System.out.println("It is still a null"); 
} 
else 
{ 
    throw new RuntimeException("This won't happen"); 
} 

Map、CollectionなどのAPIによって返された値がnullであるかどうかを確認するのは難しいことではありません。単にがプログラムによって直接比較を実行するだけです。

一方、PrintStream(System.out)によって標準出力に直接出力された結果を信用しないでください。 PrintStream.print(String)のドキュメントを参照してください。

さらに、数値やブール値を印刷するときにも同じ曖昧さが発生します。標準出力 "123"に表示されている場合は、数値か文字列値ですか?私は主張しています:値をチェックするために、PrintStreamにプリントアウトされた文字列の外観を信用してはいけません。

関連する問題