String x = (String) null;
このステートメントに例外がないのはなぜですか?
String x = null;
System.out.println(x);
null
が表示されます。しかし.toString()
メソッドはnullポインタ例外を投げるべきです。
null
を例外を発生させることなく任意の参照型にキャストできます。
println
メソッドは、オブジェクトがNULLかどうかを最初にチェックするため、NULLポインタをスローしません。 nullの場合、単に文字列"null"
を出力します。そうでなければ、そのオブジェクトのtoString
メソッドを呼び出します。
さらに詳細を追加:内部的にprintメソッドは入力オブジェクトに対してString.valueOf(object)
メソッドを呼び出します。 valueOf
メソッドでは、このチェックはnullポインタ例外を回避するのに役立ちます。
return (obj == null) ? "null" : obj.toString();
他の混乱を避けるために、nullオブジェクトで任意のメソッドを呼び出すと、特別な場合でない場合はnullポインタ例外が発生します。
null
を任意の参照型にキャストできます。引数としてnull
を扱うメソッドを呼び出すこともできます。 System.out.println(Object)
はできますが、null
値を参照してそのメソッドを呼び出すことはできません。
ところであなたがnull
値の静的メソッドを呼び出すことができるように見えるというのは難しい状況があります。
Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.
これは仕様によるものです。 null
を任意の参照型にキャストできます。そうでなければ、それを参照変数に割り当てることはできません。
メソッドがオーバーロードされ、オーバーロードされたメソッドにnullが渡された場合、コンパイラはあいまいさを解消する方法を知らないため、次のようなnull値のキャストが必要になります。
class A {
public void foo(Long l) {
// do something with l
}
public void foo(String s) {
// do something with s
}
}
new A().foo((String)null);
new A().foo((Long)null);
そうでなければ、必要なメソッドを呼び出すことができませんでした。
Println(Object)
はString.valueOf()
を使います
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Print(String)
はnullチェックを行います。
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
他の人が書いたように、あなたはすべてにnullをキャストすることができます。通常、あなたはそれを必要としないでしょう、あなたは書くことができます:
String nullString = null;
そこにキャストを置かずに。
しかし、そのようなキャストが意味をなす場合があります。
a)特定のメソッドが確実に呼び出されるようにしたい場合は、次のようにします。
void foo(String bar) { ... }
void foo(Object bar) { ... }
あなたが入力した場合、それは違いを生むだろう
foo((String) null) vs. foo(null)
b)IDEを使用してコードを生成する予定の場合たとえば、私は通常、次のような単体テストを書いています。
@Test(expected=NullPointerException.class)
public testCtorWithNullWhatever() {
new MyClassUnderTest((Whatever) null);
}
私はTDDをやっています。これは、クラス "MyClassUnderTest"がおそらくまだ存在していないことを意味します。そのコードを書き留めることで、IDEを使用して最初に新しいクラスを生成できます。そして、 "Whatever"引数をそのまま使用できるコンストラクターを生成する - IDEは、私のテストでは、コンストラクターはWhatever型の引数を1つだけ取るべきであると判断できます。
ここで多くの答えはすでに言及しました
任意の参照型にnullをキャストできます
そして
引数がnullの場合、 "null"に等しい文字列
私はそれがどこで指定されているのか疑問に思い、それをJava仕様で調べました:
そうでなければあいまいな方法を使用するとき、これは非常に便利です。たとえば、JDialogには次のシグネチャを持つコンストラクタがあります。
JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)
GraphicsConfigurationを設定したいので、このコンストラクタを使用する必要がありますが、このダイアログには親がないため、最初の引数はnullにします。を使う
JDialog(null, String, boolean, Graphicsconfiguration)
あいまいなので、この場合はサポートされている型の1つにnullをキャストすることで呼び出しを絞り込むことができます。
JDialog((Frame) null, String, boolean, GraphicsConfiguration)
このような状況では、この言語機能が便利です。
public String getName() {
return (String) memberHashMap.get("Name");
}
MemberHashMap.get( "Name")がnullを返した場合でも、例外をスローせずに上記のメソッドからnullを返させることをお勧めします。クラスが何であれ、nullはnullです。