web-dev-qa-db-ja.com

Java)の文字列と整数のNULL値

public class Test {
    public static void main(String[] args) {

        String s = null;
        String s1 = null;
        Integer i = null;
        Integer i1 = null;

        System.out.println(s+i);
        System.out.println(i+s);
        System.out.println(s+s1);

        try {
            System.out.println(i+i1);
        } catch (NullPointerException np) {         
            System.out.print("NullPointerException");       
        }
    }

}

質問は簡単です-なぜ最後の行でのみNullPointerExceptionを受け取るのですか?

49
tania

あなたのコードは2つの異なる 加法演算子 を利用しています。最初の3行は 文字列連結 を使用し、最後の行は 数値加算 を使用します。

文字列の連結は null"null"に変換するように明確に定義されています

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

したがって、NPEはありません。

2つのIntegerオブジェクトを一緒に追加するには、それらが nboxed である必要があります。これにより、null参照が逆参照され、NPEが発生します。

  • rがnullの場合、ボックス化解除の変換によりNullPointerExceptionがスローされます
60
NPE

最初の3つの_+_演算子の使用には、文字列の連結が含まれることに注意してください。最後のものだけが実際の数値です合計。文字列の連結が含まれる場合(s変数が含まれる場合)、Javaコンパイラは、パフォーマンスを向上させるために巧妙なトリックを使用します。_+_演算子をStringBuilder。たとえば、最初の行は次のように変換されます。

_StringBuilder tmp = new StringBuilder();
tmp.append(s);
tmp.append(i);
System.out.println(tmp);
_

StringBuildernullに適しているため、引数として何を渡しても、_"null"_文字列にうまく置き換えられます。

最後の行では状況が異なります。そこで、2つのIntegerオブジェクトを参照します。ここでJVMが実行できるのは、それらをボックス化解除して(i.intValue())、実際の計算を実行することだけです。 nullを開封すると、NullPointerExceptionが発生します。

17

Stringを持つものを連結(_+_演算子)すると、Stringになります。すべてのオペランドは、最初に文字列に変換され(toString()を使用するか、値_"null"_を使用)、次に連結されます。

ただし、最後の操作にはIntegersのみが含まれるため、前のルールは適用されません。連結の代わりに、加算を行います。ただし、2つのIntegersを追加するには、オブジェクト(Integers)をプリミティブ値(int)に変換します。これは、Integerがnullの場合は不可能です。そのため、NullPointerExceptionを取得します。

5
Bastien Jansen

自動開封の場合のようです。 2つのIntegers firstsecondがある場合、それらの加算の結果はfirst.intValue() + second.intValue()になります。両方ともnullであるため、結果としてNPEになります。

1
Makoto

この質問への答えは、出力から明らかであるはずであることに注意してください。

C:\Temp>Java Test
nullnull
nullnull
nullnull
NullPointerException
0
djangofan

プログラムのバイトコードを見てください。 nullオブジェクトがパラメータとしてPrintStream.print()メソッドに渡されていることに気付くでしょう。 print()メソッドのソースコードは、以下に示すようにString.valueOf()を使用します。

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}
0
ziggy