web-dev-qa-db-ja.com

int num = Integer.getInteger( "123")がNullPointerExceptionをスローするのはなぜですか?

次のコードはNullPointerExceptionをスローします。

int num = Integer.getInteger("123");

コンパイラは静的であるため、nullでgetIntegerを呼び出していますか?それは意味がありません!

何が起こっていますか?

99
user282886

大きな絵

ここには2つの問題があります。

  • Integer getInteger(String)はあなたが思っていることをしません
    • この場合、nullを返します
  • Integerからintへの割り当てにより、自動アンボックス化
    • Integernullであるため、NullPointerExceptionがスローされます

_(String) "123"_を_(int) 123_に解析するには、例えばint Integer.parseInt(String)

参照資料

Integer AP​​Iリファレンス


_Integer.getInteger_で

以下は、このメソッドが何をするかについてのドキュメントの説明です。

public static Integer getInteger(String nm) :指定された名前を持つシステムプロパティの整数値を決定します。指定された名前のプロパティがない場合、指定された名前が空またはnullの場合、またはプロパティに正しい数値形式がない場合、nullが返されます。

つまり、このメソッドはStringを_int/Integer_値に解析することとは関係ありませんが、 _System.getProperty_ 方法。

確かに、これは非常に驚きです。ライブラリにこのような驚きがあるのは残念ですが、貴重な教訓を教えてくれます。常にドキュメントを調べて、メソッドの機能を確認してください。

偶然にも、この問題のバリエーションは Return of the Puzzlers:Schlock and Awe(TS-5186) 、Josh BlochとNeal Gafterによる2009年のJavaOneテクニカルセッションのプレゼンテーション。これが最後のスライドです。

道徳

  • 奇妙でひどいメソッドがライブラリに潜んでいる
    • 無害な響きの名前が付いているものもあります
  • コードが正しく動作しない場合
    • 正しいメソッドを呼び出していることを確認してください
    • ライブラリのドキュメントを読む
  • APIデザイナー向け
    • 最小限の驚きの原則に違反しないでください
    • 抽象化階層に違反しないでください
    • 大きく異なる動作に同様の名前を使用しないでください

完全を期すために、_Integer.getInteger_に類似したこれらのメソッドもあります。

関連する質問


自動アンボクシングについて

もちろん、他の問題はNullPointerExceptionがどのようにスローされるかです。この問題に焦点を当てるために、次のようにスニペットを単純化できます。

_Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
_

Effective Java 2nd Edition、Item 49:プリミティブ型をボックス化されたプリミティブより優先する:からの引用です:

要約すると、選択肢がある場合は、ボックスプリミティブよりもプリミティブを優先して使用してください。プリミティブ型はよりシンプルで高速です。ボックス化されたプリミティブを使用する必要がある場合は、注意してください!オートボクシングは、ボックス化されたプリミティブを使用することによる冗長性を減らしますが、危険性は減らしません。プログラムが_==_演算子を使用して2つのボックス化されたプリミティブを比較すると、IDの比較が行われますが、これはほぼ間違いなく目的の比較ではありません。プログラムがボックス化されたプリミティブとボックス化されていないプリミティブを含む混合タイプの計算を行う場合、ボックス化解除を行い、プログラムがボックス化解除を行う場合、NullPointerExceptionをスローできます。最後に、プログラムがプリミティブ値をボックス化すると、コストがかかり不必要なオブジェクトが作成される可能性があります。

ボックス化されたプリミティブを使用する以外に選択肢がない場所があります。ジェネリック、ただしそうでない場合は、ボックス化プリミティブを使用する決定が正当化されるかどうかを真剣に検討する必要があります。

関連する質問

205

http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html

getInteger「指定された名前のシステムプロパティの整数値を決定します。」

あなたはこれを求めている:

Integer.parseInt("123")
16

メソッドのドキュメントを確認してください getInteger() 。このメソッドでは、Stringパラメーターは、指定された名前を持つシステムプロパティの整数値を決定するシステムプロパティです。前述のように、「123」はシステムプロパティの名前ではありません here 。この文字列をintに変換する場合は、int num = Integer.parseInt("123")としてメソッドを使用します。

6
Sonal Patil