次のコードがスローしNullPointerException
ます。
int num = Integer.getInteger("123");
コンパイラーはgetInteger
静的なのでnull を呼び出していますか?それは意味がありません!
何が起こっていますか?
次のコードがスローしNullPointerException
ます。
int num = Integer.getInteger("123");
コンパイラーはgetInteger
静的なのでnull を呼び出していますか?それは意味がありません!
何が起こっていますか?
回答:
ここでは、2つの問題があります。
Integer getInteger(String)
あなたが思っていることをしていません
null
この場合は戻るInteger
toへの割り当ては、int
自動アンボックス化を引き起こします
Integer
されnull
、NullPointerException
スローされますを解析(String) "123"
するには(int) 123
、たとえばを使用できますint Integer.parseInt(String)
。
Integer
APIリファレンスInteger.getInteger
このメソッドが何をするかについてのドキュメントの説明は次のとおりです。
public static Integer getInteger(String nm)
:指定された名前のシステムプロパティの整数値を決定します。指定した名前のプロパティがない場合、指定した名前が空またはの場合null
、またはプロパティの数値形式が正しくない場合は、null
が返されます。
つまり、このメソッドはa String
をint/Integer
値に解析することとは関係ありませんが、メソッドと関係がありますSystem.getProperty
。
確かにこれは驚くべきことです。ライブラリにこのような驚きがあるのは残念ですが、それはあなたに貴重な教訓を教えてくれます:常にドキュメントを調べてメソッドが何をするかを確認してください。
偶然にも、この問題のバリエーションがReturn of the Puzzlers:Schlock and Awe(TS-5186)、Josh BlochとNeal Gafterの2009 JavaOne Technical Sessionプレゼンテーションで紹介されました。これが最後のスライドです。
道徳
- 奇妙で恐ろしい方法がライブラリに潜んでいる
- 一部には無害な響きの名前があります
- コードが正しく動作しない場合
- 適切なメソッドを呼び出していることを確認してください
- ライブラリのドキュメントを読む
- APIデザイナー向け
- 最小の驚きの原則に違反しないでください
- 抽象化階層に違反しないでください
- まったく異なる動作に類似した名前を使用しないでください
完全を期すために、次のような方法もありますInteger.getInteger
。
もちろん、もう1つの問題は、どのようNullPointerException
にスローされるかです。この問題に集中するために、次のようにスニペットを簡略化できます。
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
これは、Effective Java 2nd Edition、Item 49:Preferプリミティブ型よりボックス化されたプリミティブからの引用です。
要約すると、選択肢があるときはいつでも、ボックス化されたプリミティブよりもプリミティブを使用してください。プリミティブ型はよりシンプルで高速です。ボックス化されたプリミティブを使用する必要がある場合は、注意してください。自動ボックス化は、ボックス化されたプリミティブを使用することの危険性ではなく、冗長性を減らします。プログラムが2つのボックス化されたプリミティブを
==
演算子と比較するとき、同一性比較を行いますが、これはほぼ確実に望んでいることではありません。プログラムがボックス化されたプリミティブとボックス化されていないプリミティブを含む混合型の計算を行う場合はボックス化解除を行い、プログラムがボックス化解除を行う場合はをスローしNullPointerException
ます。最後に、プログラムがプリミティブ値をボックス化すると、高価で不要なオブジェクトが作成される可能性があります。
ジェネリックなどのボックス化されたプリミティブを使用せざるを得ない場所がありますが、それ以外の場合は、ボックス化されたプリミティブを使用する決定が正当化されるかどうか真剣に検討する必要があります。
Integer.getInteger(s)
大体同じInteger.parseInt(System.getProperty(s))
ですか?2番目の方がより詳細ですが、システムプロパティから情報を取得しているという事実を強調するので、2番目の方が好きだと思います。
Integer.decode
代わりにを使用Integer.parseInt
して、先頭を検索し0x
たり0
、数値をそれぞれ16進数または8進数として解析したりしました。
NullPointerException
質問している人のために?:programmers.stackexchange.com/questions/158908/...
http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.htmlから:
getInteger '指定された名前のシステムプロパティの整数値を決定します。'
あなたはこれを求めている:
Integer.parseInt("123")
メソッドgetInteger()のドキュメントを確認してください。このメソッドでは、String
パラメーターは、指定された名前のシステムプロパティの整数値を決定するシステムプロパティです。ここで説明するように、「123」はシステムプロパティの名前ではありません。この文字列をに変換する場合int
は、メソッドをasとして使用し
int num = Integer.parseInt("123")
ます。