web-dev-qa-db-ja.com

Javaでnullを使った型キャスト中に例外が発生しない

String x = (String) null;

このステートメントに例外がないのはなぜですか?

String x = null;
System.out.println(x);

nullが表示されます。しかし.toString()メソッドはnullポインタ例外を投げるべきです。

195
Vicky

nullを例外を発生させることなく任意の参照型にキャストできます。

printlnメソッドは、オブジェクトがNULLかどうかを最初にチェックするため、NULLポインタをスローしません。 nullの場合、単に文字列"null"を出力します。そうでなければ、そのオブジェクトのtoStringメソッドを呼び出します。

さらに詳細を追加:内部的にprintメソッドは入力オブジェクトに対してString.valueOf(object)メソッドを呼び出します。 valueOfメソッドでは、このチェックはnullポインタ例外を回避するのに役立ちます。

return (obj == null) ? "null" : obj.toString();

他の混乱を避けるために、nullオブジェクトで任意のメソッドを呼び出すと、特別な場合でない場合はnullポインタ例外が発生します。

278
Juned Ahsan

nullを任意の参照型にキャストできます。引数としてnullを扱うメソッドを呼び出すこともできます。 System.out.println(Object)はできますが、null値を参照してそのメソッドを呼び出すことはできません。

ところであなたがnull値の静的メソッドを呼び出すことができるように見えるというのは難しい状況があります。

Thread t = null;
t.yield(); // Calls static method Thread.yield() so this runs fine.
139
Peter Lawrey

これは仕様によるものです。 nullを任意の参照型にキャストできます。そうでなければ、それを参照変数に割り当てることはできません。

33
André Stannek

メソッドがオーバーロードされ、オーバーロードされたメソッドに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);

そうでなければ、必要なメソッドを呼び出すことができませんでした。

16
Mewel

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);
}
4
rocketboy

他の人が書いたように、あなたはすべてに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つだけ取るべきであると判断できます。

3
GhostCat

ここで多くの答えはすでに言及しました

任意の参照型にnullをキャストできます

そして

引数がnullの場合、 "null"に等しい文字列

私はそれがどこで指定されているのか疑問に思い、それをJava仕様で調べました:

null参照は常に任意の参照型(5.2、5.3、5.5)に代入またはキャストすることができます。

参照がnullの場合、文字列 "null"(4つのASCII文字n、u、l、l)に変換されます。

3
Arigion

印刷

オブジェクトを印刷します。 String.valueOf(Object)メソッドによって生成された文字列はバイトに変換されます。

ValueOf

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

オブジェクトがnullの場合、単に値 "null"の文字列を返します。

2
Jeroen Vannevel

そうでなければあいまいな方法を使用するとき、これは非常に便利です。たとえば、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)
2
Marten Jacobs

このような状況では、この言語機能が便利です。

public String getName() {
  return (String) memberHashMap.get("Name");
}

MemberHashMap.get( "Name")がnullを返した場合でも、例外をスローせずに上記のメソッドからnullを返させることをお勧めします。クラスが何であれ、nullはnullです。

0
Changgull Song