2012-04-17 16 views
5

次のスニペットは、単純なJavaコードを使用しています。Javaで不明なNullPointerException

package pkg; 

final public class Main 
{ 
    final private class Demo 
    { 
     private Integer value = null; 

     public Integer getValue() 
     { 
      return value; 
     } 
    } 

    private Integer operations() 
    { 
     Demo demo = new Demo(); 
     return demo==null?new Integer(1):demo.getValue(); 
    } 

    public static void main(String[] args) 
    { 
     Main main=new Main(); 
     System.out.println("Value = " + String.valueOf(main.operations())); 
    } 
} 

上記のコードは問題なく動作し、コンソールにValue = nullと表示されます。以下return文において

return demo==null?new Integer(1):demo.getValue(); 

タイプDemoのオブジェクトdemonullないので、demo.getValue()ある:後に発現がnullを返す内部Demoクラス内getValue()を起動している実行されます最後に、Stringに変換されてコンソールに表示されます。

しかし、私は以下のようなoperations()方法何か、

private Integer operations() 
{ 
    Demo demo = new Demo();  
    return demo==null?1:demo.getValue(); 
} 

を変更すると、それはNullPointerExceptionをスローします。どうやって?


私は

NullPointerExceptionをスローしません)私はこのreturn声明

return demo==null?new Integer(1):demo.getValue(); 

を使用するときにそれが動作を意味し、私は次のよう似たようなreturn声明

を使用する場合
return demo==null?1:demo.getValue(); 

の場合はNullPointerExceptionとなります。どうして?

+3

http://stackoverflow.com/questions/7811608/java-npe-in​​-ternary-operator-with-autoboxing –

+0

[奇妙なJava NullPointerExceptionとオートボックスの可能な複製](http://stackoverflow.com/questions/) 3265948/strange-java-nullpointexception-with-autoboxing) – Pops

答えて

11

このステートメントは:

return demo==null?1:demo.getValue(); 

実際にこのようなものに変換されている:条件式の型は、ルールに基づいてint(ないInteger)であると判断された

int tmp = demo == null ? 1 : demo.getValue().intValue(); 
return (Integer) tmp; 

laid out in the JLS, section 15.25binary numeric promotion (5.6.2)を使用します。ヌル参照からintへの変換により、NullPointerExceptionがトリガされます。

3
return demo==null?new Integer(1):demo.getValue(); 

この場合、式の型はIntegerであり、nullは正当な値です。

return demo==null?1:demo.getValue(); 

この場合、式の型はintであるため、Integerの戻り値は自動的にアンボックスされます。そしてそれがヌルであるので、それはNPEを投げます。