次のコードがスローされNullPointerException
ます:
int num = Integer.getInteger("123");
getInteger
静的なので、コンパイラはnullを呼び出していますか?それは意味がありません!
何が起こっていますか?
次のコードがスローされNullPointerException
ます:
int num = Integer.getInteger("123");
getInteger
静的なので、コンパイラはnullを呼び出していますか?それは意味がありません!
何が起こっていますか?
ここでは2つの問題があります。
Integer getInteger(String)
あなたが思っていることをしません
null
この場合は戻りますInteger
からの割り当てint
により、自動開開
が発生しますInteger
ますnull
NullPointerException
に解析(String) "123"
するに(int) 123
は、たとえばを使用できますint Integer.parseInt(String)
。
Integer
APIリファレンスInteger.getInteger
このメソッドの機能について、ドキュメントに記載されている内容は次のとおりです。
public static Integer getInteger(String nm)
:指定された名前のシステムプロパティの整数値を決定します。指定された名前のプロパティがない場合、指定された名前が空またはnull
である場合、またはプロパティの数値形式が正しくない場合は、null
が返されます。
つまり、このメソッドはaString
をint/Integer
値に解析することとは関係がなく、むしろSystem.getProperty
メソッドと関係があります。
確かに、これは非常に驚きです。ライブラリにこのような驚きがあるのは残念ですが、それは貴重な教訓を教えてくれます。常にドキュメントを調べて、メソッドが何をするかを確認してください。
偶然にも、この問題のバリエーションは、パズルのリターン:Schlock and Awe(TS-5186)、Josh Bloch、NealGafterの2009JavaOneテクニカルセッションのプレゼンテーションで取り上げられました。最後のスライドは次のとおりです。
道徳
- 奇妙でひどい方法が図書館に潜んでいる
- いくつかは無害な響きの名前を持っています
- コードが誤動作した場合
- 適切なメソッドを呼び出していることを確認してください
- ライブラリのドキュメントを読む
- APIデザイナー向け
- 驚き最小の原則に違反しないでください
- 抽象化階層に違反しないでください
- 大きく異なる動作に類似した名前を使用しないでください
完全を期すために、次のような方法もありますInteger.getInteger
。
もちろん、もう1つの問題は、がどのようNullPointerException
にスローされるかです。この問題に焦点を当てるために、次のようにスニペットを簡略化できます。
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
これは、Effective Java 2nd Edition、アイテム49からの引用です。ボックス化されたプリミティブよりもプリミティブ型を優先します。
要約すると、選択できる場合は常に、ボックス化されたプリミティブよりもプリミティブを使用します。プリミティブ型はより単純で高速です。ボックス化されたプリミティブを使用する必要がある場合は、注意してください。自動ボクシングは、ボックス化されたプリミティブを使用する際の冗長性を軽減しますが、危険性は軽減しません。プログラムが2つのボックス化されたプリミティブを
==
演算子と比較するとき、それはID比較を行いますが、これはほぼ確実にあなたが望むものではありません。プログラムがボックス化されたプリミティブとボックス化されていないプリミティブを含む混合型の計算を行う場合、プログラムはボックス化解除を行い、プログラムがボックス化解除を行う場合、をスローする可能性がありNullPointerException
ます。最後に、プログラムがプリミティブ値をボックス化すると、コストがかかり、不要なオブジェクトが作成される可能性があります。
ジェネリックなど、ボックス化されたプリミティブを使用せざるを得ない場所もありますが、それ以外の場合は、ボックス化されたプリミティブを使用する決定が正当化されるかどうかを真剣に検討する必要があります。
http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.htmlから:
getInteger'指定された名前のシステムプロパティの整数値を決定します。
あなたはこれを求めている:
Integer.parseInt("123")
getInteger()メソッドのドキュメントを確認してください。このメソッドでは、String
パラメーターは、指定された名前のシステムプロパティの整数値を決定するシステムプロパティです。ここで説明するように、「123」はシステムプロパティの名前ではありません。この文字列をに変換する場合int
は、メソッドをとして使用し
int num = Integer.parseInt("123")
ます。