Javaでnullを使用した型キャスト中に例外はありません


回答:


323

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

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

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

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

混乱の残りについては、特別な場合ではないにしても、nullオブジェクトのメソッドを呼び出すと、nullポインター例外がスローされます。


1
@JunedAhsanどのような特別な場合にNPEをスローしないのですか?
Holloway 2014年

@Trengot下記のピーターの回答で言及されているものをチェックしてください。
Juned Ahsan、2014

144

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

ところで、null値に対して静的メソッドを呼び出すことができるように見えるトリッキーな状況があります。

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

12
ワオ。質問された場合、例外がスローされることを100%確信しています。確かにトリッキーなケースです。
Magnilex 2015

2
@Magnilex:もちろん!これは典型的なOCPJP試験のトリック問題です。
ccpizza '17年

3
t.yield() -> Thread.yeld() とにかく、バイトコードのコンパイラはそれを「最適化」するためではないでしょうか?どのようfinal int i = 1; while (i == 1)に最適化されるのかと同様while(true)
SGal 2018

@SGal 2番目の最適化はAFAIKではなく、最初の最適化は必須ではないため、さらに優れています。
Paul Stelian

36

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


ありがとう!参照変数へのnullの割り当てに関するこのメモは非常に役立ちます。
最大

22

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

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


ほとんどの場合、キャストは暗黙的です。たとえばString bar = null;null値をにキャストしますString。これまでのところ、メソッドがオーバーロードされているテストでnullを明示的にキャストするだけで、null入力を使用してその動作をテストしたかったのです。それでも、知っておくと良いのは、あなたの答えが見つかる前に、同じような答えを書こうとしていたことです。
Vlasec

おもしろい事実:l instanceof Longそして、これらの場合にs instanceof String戻りfalseます。
Attila Tanyi

7

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

5

ここですでに述べた多くの答え

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

そして

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

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

null参照は、常に任意の参照タイプに割り当てるか、キャストすることができます(§5.2、§5.3、§5.5)。

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


3

他の人が書いたように、すべてに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を使用して最初に新しいクラスを生成できます。そして、「箱から出して」「何でも」引数を受け入れるコンストラクターを生成する-IDEは、コンストラクターがWhatever型の引数を1つだけ取る必要があることをテストから判断できます。


2

印刷

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

ValueOf

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

オブジェクトがの場合、値「null」の文字列を返すだけですnull


2

これは、あいまいな方法を使用する場合に非常に便利です。たとえば、JDialogには次のシグネチャを持つコンストラクタがあります。

JDialog(Frame, String, boolean, GraphicsConfiguration)
JDialog(Dialog, String, boolean, GraphicsConfiguration)

GraphicsConfigurationを設定するため、このコンストラクタを使用する必要がありますが、このダイアログの親がないため、最初の引数はnullにする必要があります。使用する

JDialog(null, String, boolean, Graphicsconfiguration) 

あいまいなので、この場合は、サポートされている型のいずれかにnullをキャストすることで、呼び出しを絞り込むことができます。

JDialog((Frame) null, String, boolean, GraphicsConfiguration)

0

この言語機能は、この状況で便利です。

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

memberHashMap.get( "Name")がnullを返した場合でも、例外をスローせずに上記のメソッドがnullを返すようにしたいでしょう。クラスが何であれ、nullはnullです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.