次のコードはNullPointerException
をスローします。
int num = Integer.getInteger("123");
コンパイラは静的であるため、nullでgetInteger
を呼び出していますか?それは意味がありません!
何が起こっていますか?
ここには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
が返されます。
つまり、このメソッドは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
をスローできます。最後に、プログラムがプリミティブ値をボックス化すると、コストがかかり不必要なオブジェクトが作成される可能性があります。
ボックス化されたプリミティブを使用する以外に選択肢がない場所があります。ジェネリック、ただしそうでない場合は、ボックス化プリミティブを使用する決定が正当化されるかどうかを真剣に検討する必要があります。
http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger「指定された名前のシステムプロパティの整数値を決定します。」
あなたはこれを求めている:
Integer.parseInt("123")
メソッドのドキュメントを確認してください getInteger() 。このメソッドでは、String
パラメーターは、指定された名前を持つシステムプロパティの整数値を決定するシステムプロパティです。前述のように、「123」はシステムプロパティの名前ではありません here 。この文字列をint
に変換する場合は、int num = Integer.parseInt("123")
としてメソッドを使用します。