2013-02-20 11 views
5

次のコードを実行した場合、ヌル箱入りオブジェクトをアンボクシングスロー予期しないNullPointerExceptionが

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) 

がどのように何のコンパイラの警告か何かがありません来るあなたは、次のスタックトレースを得るのだろうか? IMHOそれはunboxingとかなり厄介な微妙な、または多分私はちょうどナイーブだ。 @Javierが提供する答えにに追加


Eclipseを使用している場合、あなたはこの有効にするには、次の実行する必要があります。ウィンドウに

  1. 移動し>設定>をJava>コンパイラ>エラー/警告
  2. は、私はあなたが使用しているIDE知らない「警告」のどちらかに潜在的なプログラミングの問題
  3. トグルボクシングとアンボクシング変換を展開、または「エラー」
  4. をタップし、「OK」
+0

わかりません。なぜNPEが起こるのか、これはちょうど暴言なのか尋ねていますか?具体的な答えるべき質問は何でしょうか? – madth3

答えて

5

Eclipseには、ボクシングとコンボボックス解除の警告を有効にするオプションがあります。ヌルは即座にアンボックスされていないので、Bar.getId()を経由してヌルポインタアクセスとして検出することはできません。

あなたがnull上の任意のメソッドを使用するか、nullと意味がない何かをしようとするInteger型の式は、int型
Foo.javaライン3

+0

私はEclipseを〜3年間使用していましたが、私はそれを知らなかったのです!甘い! – mre

+2

日食はボクシングなしでunboxing警告をオンにすることはできません迷惑だ! https://bugs.eclipse.org/bugs/show_bug.cgi?id=163065 – Kyle

3

にアンボクシングでNullPointerExceptionをスローします。

Autounboxingは[Integer object].intValue()方法(または類似)で実装するので、あなたがメソッドを呼び出すnull持つことができないので、それはNullPointerExceptionをスローしています。

希望すると便利です。

+1

+1裏にあるintValueについて、お礼 – mre

0

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

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

int getId(){ 
    if(id!=null){ 
     return id; 
    } 
    // return other or throw a checked exception. 
} 
0

完全に合理的な実行時例外のようです。あなたの主なコードは:

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

nullポインタの例外については誰も驚かないでしょう。 Barクラスはnullを返し、nullオブジェクトポインタを単純な値にすることはできません。 Barクラスの実装を変更して、idをnull以外の値に初期化することができます。このコードブロックはBarクラスとは別にコンパイルすることができるため、Barクラスの動的動作に関する前提はこのコードブロックには必ずコード化されていないはずです。

これはおそらく明らかですが、実際の解決策は、Integerではなく、idメンバーにintを使用することです。

private static class Bar{ 
    private final int id; 

    public Bar(){ 
     this(0); 
    } 

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

    public int getId(){ 
     return id; 
    } 
} 

(しかし、私はあなたがすでにこの:-)を知っていたと仮定)、

+0

私は例外が不合理であるとは言わなかったが、特に私のIDEはデフォルトで無視するように選択して以来です。 – mre

+0

OK、私は "期待される"と "予期しない"ものを取り戻そうとしていました。これは実行時の例外であり、静的解析では必ずしも決定できないものです。この状況でIDEがどのように動作すると思いますか? – AgilePro

+0

私はIDEが少なくともデフォルトで私に警告することを期待しました。私が言ったように、私はそれがかなり微妙なランタイム例外だと思う。 – mre

4

この動作はJDK™ 5.0 Documentationに記載されていることを思わ

:これは、その後、何の問題を持っていませんintIntegerの区別をほとんど無視することができます。 にはいくつかの警告があります。 Integer式は、ヌル値を持つことができます。 プログラムがautounboxヌルにしようとすると、NullPointerExceptionがスローされます。

0

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

関連する問題