3

序章

私はこの問題に数分立ち往生していました。だから、それはおそらく他の誰かを助けるだろうし、それは楽しいバグです. しかし、最初の質問を解決すると、別の質問に移動しました。


最初のパズルの質問:

次のコードを検討してください。

public void setValue(ValueWrapper valueWrapper) {

        if (anotherValueWrapper == null) {
            anotherValueWrapper = new AnotherValueWrapper();
        }

        anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
    }

事実 :

  • このコードはコンパイルされます
  • ゲッターとセッターは標準です(フィールドを返すか設定するだけのコードはありません)

問題

実行中に、コードが失敗して null ポインター例外を返すケースが 1 つあります。

最初のパズルの質問は次のとおりです。このコードが NullPointerException になるのはいつですか?

最初の質問が見つからない場合はネタバレになるので、2 番目の質問は見ないでください。


2 番目の質問

わかりました、あなたはそれを見つけます(または多分見つけないでしょう):問題は、AnotherValueWrapperが次のように書かれているときです:

public class AnotherValueWrapper {
  private long value;

  public long getValue() { return value; }

  public void setValue(long value) { this.value = value; }
}

および ValueWrapper:

public class ValueWrapper {
  private Long value;

  public Long getValue() { return value; }

  public void setValue(Long value) { this.value = value; }
}

2 番目の質問は次のとおりです。

私が書く場合:

anotherValueWrapper.setValue(null);

また

anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());

if は(オブジェクト)anotherValueWrapper.setValueではなくプリミティブ (long) を取るため、コンパイルされません。Long

しかし、このコードはコンパイルされます:

anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());

なんで ?

4

4 に答える 4

2

anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());

null実際にはLong、自動ボックス化しようとするタイプであるlongため、ヌルポインター例外をスローします

于 2013-02-21T15:57:40.010 に答える
2

setValue(null) または setValue("test") を実行すると、Object クラスと String クラスが明示的に渡され、プリミティブ型 long と一致しません。

ただし、Java のオートボクシング機能により、オブジェクト型 Long を渡すことは問題ありません。これは、プリミティブ型とそのオブジェクト ラッパーとの間で自動的に変換します。Long オブジェクトを anotherValueWrapper の setValue() メソッドに渡すと、内部で Long の longValue() メソッドが実行され、Long オブジェクトが null の場合は NullPointerException が発生します。

于 2013-02-21T16:03:38.107 に答える
0

LongStringは交換可能ではありませんが、とLongnull..

于 2013-02-21T15:55:54.750 に答える
0
anotherValueWrapper.setValue(null);

プリミティブを null に設定できないため、コンパイルされません。AnotherValueWrapper は、「値」フィールドに long (プリミティブ) を使用します。

anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());

「test」は文字列であり、長い変数に割り当てることができないため、コンパイルされません。

于 2013-02-21T15:56:19.043 に答える