2011-10-18 3 views
0

なぜこのコードはNPEを引き起こすのですか? Findbugsは、このことが起こりうることをヒントにしてくれます:-)Java:単項if - npe

アイデア?

public Integer whyAnNPE() { 
    return 1 == 2 ? 1 : 1 == 2 ? 1 : null; 
} 
+6

これはJavaではありません - どのような言語ですか? –

+0

例を完成させます。 – CannyDuck

+1

まだそれはJavaではありませんが、今はNPEが「時々」という理由が明らかです。 –

答えて

4

編集:私はこの回答を書いたときに問題のコードは存在しませんでした。

は、ここでは少し明確にするために、別の方法です:

public static Integer maybeCrash(boolean crash) { 
    return true ? (crash ? null : 1) : 0; 
} 

重要な点は、我々がここに条件式を持っているということです。内側のものは、section 15.25で指定されたタイプの決定の最後の箇条書きポイントのためにタイプIntegerです。

public static Integer maybeCrash(boolean crash) { 
    Integer tmp = null; 
    return true ? tmp : 0; 
} 

今条件式を残りため、以前の箇条書きが適用され、binary numeric promotionが実行されます。

は、その時点で、我々はこのような状況を持っています。これにより、最初のステップとしてunboxingが呼び出されます。これは失敗します。すなわち

、このような条件:

condition ? Integer : int 

は、潜在的にintIntegerをアンボクシング含む:

condition ? null-type : int 

は、潜在的にIntegerintをボクシングが、このような条件を含みます。


オリジナル答え

ここでは、実際に有効なJavaであるというより単純な例です:

public class Test { 
    public static void main(String[] args) { 
     int x = args.length == 0 ? 1 : null; 
    } 
} 

は、これは事実である:

int tmp; 
if (args.length == 0) { 
    tmp = 1; 
} else { 
    Integer boxed = null; 
    tmp = boxed.intValue(); 
} 

明らかにここにアンボクシングのステップになりますgo bang。基本的には、ヌル式をIntegerに暗黙的に変換し、Integerからintにアンボックスすることが基本です。

+0

私はそれがここにどのように適用されるのか分かりません。彼は 'Integer'オブジェクトを返すので、ヌルはunboxされません。彼はそれを 'int'に代入する必要があります。その場合、関数はバグの一部ではありません(Integerを返すメソッドからヌルを返すことは完全に良いです) – Voo

+0

@Voo:いいえ、条件式の型はまだintです - それは再びボックス化されています。私が答えたとき、問題のコードは存在しませんでした - 私は今編集します。 –

+0

@Voo:それはもう意味をなさないかどうかを見てください:) –

0

プリミティブデータ型(int、long、float、doubleなど)はnullにできません。オブジェクトのみがnullになります。また、擬似コードではなく、メソッドの完全なシグネチャを確認すると便利です