6

次のコードを実行すると、

public class Foo{
    public static void main(String[] args){
        int id = new Bar().getId(); // throws unexpected NullPointerException
    }

    private static class Bar{
        private final Integer id;

        public Bar(){
            this(null);
        }

        public Bar(Integer id){
            this.id = id;
        }

        public Integer getId(){
            return id;
        }
    }
}

次のスタックトレースを取得します。

Exception in thread "main" java.lang.NullPointerException
    at Foo.main(Foo.java:3)

コンパイラの警告などがないのはなぜですか? 私見、それはボックス化解除のかなり厄介な微妙さです。または、私が単純なだけかもしれません。


@Javierが提供する回答に加えて、Eclipse を使用している場合は、これを有効にするために次の操作を行う必要があります。

  1. Window> Preferences> Java> Compiler>に移動しますErrors/Warnings
  2. 潜在的なプログラミングの問題を展開する
  3. ボックス化とボックス化解除の変換を「警告」または「エラー」に切り替えます
  4. 「OK」をタップ
4

6 に答える 6

6

で任意のメソッドを使用しようとしnullたり、で意味をなさないことを実行しようとするとnull、がスローされNullPointerExceptionます。

[Integer object].intValue()自動アンボックスはメソッド(または同様のもの)で実装されているため、メソッドを呼び出すNullPointerExceptionことができないため、がスローされます。null

お役に立てれば!

于 2013-02-20T23:54:12.463 に答える
6

どの IDE を使用しているかはわかりませんが、Eclipse には、ボックス化およびボックス化解除の変換に関する警告を有効にするオプションがあります。null はすぐにアンボックス化されるのではなく、Bar.getId().

Integer 型の式は int
Foo.java 行 3にボックス化されていません

于 2013-02-20T23:49:49.757 に答える
0

NullPointerExceptionRuntimeExceptionコードをコンパイルするときに IDE が検出できないよりもです。

代わりに、アンボックス化する前に null をチェックすることをお勧めします。

int getId(){
    if(id!=null){
        return id;
    }
    // return other or throw a checked exception.
}
于 2013-02-20T23:58:20.790 に答える
0

ボクシングは、Integer のようなオブジェクトをネイティブの同等の 'int' にキャストするための構文糖衣にすぎません。ネイティブは null にできませんが、オブジェクトはできます。これらの場合、ボクシング メカニズムは NullPointerExceptions を防止しません。

于 2013-02-24T04:15:43.003 に答える
0

完全に合理的な実行時例外のようです。メインコードが次の場合:

public static void main(String[] args){        
    Integer idObj = new Bar().getId();
    int id = idObj;   // throws NullPointerException
}

ヌル ポインター例外に驚く人はいないでしょう。Bar クラスは null を返し、null オブジェクト ポインターは単純な値に変換できません。Bar クラスの実装は、id を非 null 値に初期化するように変更される場合があります。このコード ブロックは、Bar クラスとは別にコンパイルできるため、Bar クラスの動的な動作に関する仮定をこのコード ブロックにコーディングしないでください。

これはおそらく明らかですが、実際の解決策はint、 の代わりに id メンバーを使用することですInteger。したがって、これには問題はありません。

private static class Bar{
    private final int id;

    public Bar(){
        this(0);
    }

    public Bar(int id){
        this.id = id;
    }

    public int getId(){
        return id;
    }
}

(しかし、私はあなたがすでにこれに気づいていたと思います:-))

于 2013-02-21T00:05:23.533 に答える