Java三元表示式解箱和箱詰めによるNullPointerException

1431 ワード

今日コードを書く時に1つのとても奇妙な空のポインタの異常に出会って、たぶんコードは以下の通りです
public class User {

    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}


User  user = new User();
Integer id = user == null ? 0 : user.getId();
System.out.println(id);

コードを見ると問題ないはずですが、実行中にjavaに報告しました.lang.Null PointerException異常.コンパイルされたコードを次のように表示します.
User user = new User();
Integer id = Integer.valueOf(user == null ? 0 : user.getId().intValue());
System.out.println(id);

解体と梱包はjavaコードの構文糖であり、コンパイル段階で完了していることがわかります.コンパイルフェーズでは、演算に異なるタイプがあり、タイプ変換に関連し、コンパイラはオブジェクトタイプを基本タイプに変換して計算することを優先します.なぜならuser.getId()はnullでnullを呼び出すintValue()メソッドは空のポインタ異常を放出します.次の2つの状況は間違っていません.
User  user = new User();
Integer id = user == null ? 0 : null;
System.out.println(id);


User  user = new User();
Integer id = user == null ? Integer.valueOf(0) : user.getId();
System.out.println(id);

1つ目は、コンパイラが下への転換がエラーになることを発見し、上への転換、0をIntegerに転換することである.valueOf(0)は,2つ目はいずれもオブジェクトタイプであり,モデルチェンジを必要としない.コンパイルした結果はそれぞれ
User user = new User();
Integer id = user == null ? Integer.valueOf(0) : null;
System.out.println(id); 


User user = new User();
Integer id = user == null ? Integer.valueOf(0) : user.getId();
System.out.println(id);

まとめ:
三元表現では、できるだけ同じタイプを使用します.基本タイプとオブジェクトタイプを混用しないでください.