JavaでのNumberFormatExceptionの理解
1. 序章
Javaは、文字列を数値型に変換できない場合、 NumberFormatException – 未チェックの例外–をスローします。
チェックなしであるため、Javaはそれを処理または宣言することを強制しません。
このクイックチュートリアルでは、 JavaでNumberFormatExceptionが発生する原因と、それを回避または処理する方法について説明およびデモンストレーションします。
2. NumberFormatExceptionの原因
NumberFormatExceptionを引き起こすさまざまな問題があります。 たとえば、Javaの一部のコンストラクタとメソッドはこの例外をスローします。
それらのほとんどについては、以下のセクションで説明します。
2.1. コンストラクターに渡される非数値データ
数値以外のデータを使用してIntegerまたはDoubleオブジェクトを作成する試みを見てみましょう。
これらのステートメントは両方ともNumberFormatExceptionをスローします。
Integer aIntegerObj = new Integer("one");
Double doubleDecimalObj = new Double("two.2");
1行目のIntegerコンストラクターに無効な入力「one」を渡したときに取得したスタックトレースを見てみましょう。
Exception in thread "main" java.lang.NumberFormatException: For input string: "one"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.<init>(Integer.java:867)
at MainClass.main(MainClass.java:11)
NumberFormatExceptionをスローしました。 parseInt()を内部的に使用して入力を理解しようとしたときに、Integerコンストラクターが失敗しました。
Java Number APIは単語を数値に解析しないため、コードを期待値に変更するだけでコードを修正できます。
Integer aIntegerObj = new Integer("1");
Double doubleDecimalObj = new Double("2.2");
2.2. 非数値データを含む文字列の解析
コンストラクターでの解析に対するJavaのサポートと同様に、 par seInt()、parseDouble()、
これらを使用して同じ種類の変換を実行しようとすると、次のようになります。
int aIntPrim = Integer.parseInt("two");
double aDoublePrim = Double.parseDouble("two.two");
Integer aIntObj = Integer.valueOf("three");
Long decodedLong = Long.decode("64403L");
次に、同じ種類の誤った動作が表示されます。
そして、同様の方法でそれらを修正できます。
int aIntPrim = Integer.parseInt("2");
double aDoublePrim = Double.parseDouble("2.2");
Integer aIntObj = Integer.valueOf("3");
Long decodedLong = Long.decode("64403");
2.3. 無関係な文字を含む文字列を渡す
または、文字列を入力に空白や特殊文字などの外部データを含む数値に変換しようとした場合:
Short shortInt = new Short("2 ");
int bIntPrim = Integer.parseInt("_6000");
次に、以前と同じ問題が発生します。
文字列を少し操作するだけで、これらを修正できます。
Short shortInt = new Short("2 ".trim());
int bIntPrim = Integer.parseInt("_6000".replaceAll("_", ""));
int bIntPrim = Integer.parseInt("-6000");
3行目では、ハイフン文字をマイナス記号として使用して、負の数が許可されていることに注意してください。
2.4. ロケール固有の数値形式
ロケール固有の番号の特殊なケースを見てみましょう。 ヨーロッパの地域では、コンマは小数点以下の桁数を表す場合があります。 たとえば、「4000,1」は10進数の「4000.1」を表す場合があります。
デフォルトでは、コンマを含む値を解析しようとすると、NumberFormatExceptionが発生します。
double aDoublePrim = Double.parseDouble("4000,1");
この場合、コンマを許可し、例外を回避する必要があります。 これを可能にするには、Javaはここでコンマを小数として理解する必要があります。
NumberFormat を使用することで、ヨーロッパ地域のカンマを許可し、例外を回避できます。
例として、フランスの Locale を使用して、実際の動作を見てみましょう。
NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE);
Number parsedNumber = numberFormat.parse("4000,1");
assertEquals(4000.1, parsedNumber.doubleValue());
assertEquals(4000, parsedNumber.intValue());
3. ベストプラクティス
NumberFormatExceptionに対処するのに役立ついくつかのグッドプラクティスについて話しましょう。
- アルファベットまたは特殊文字を数字に変換しようとしないでください– JavaNumberAPIはそれを実行できません。
- 正規表現を使用して入力文字列を検証し、無効な文字の例外をスローしたい場合があります。
- trim()や replaceAll()などのメソッドを使用して、予測可能な既知の問題に対して入力をサニタイズできます。
- 場合によっては、入力の特殊文字が有効な場合があります。 そのため、 NumberFormat、などを使用して特別な処理を行います。これは、多数のフォーマットをサポートします。
4. 結論
このチュートリアルでは、JavaでのNumberFormatExceptionとその原因について説明しました。 この例外を理解すると、より堅牢なアプリケーションを作成するのに役立ちます。
さらに、いくつかの無効な入力文字列で例外を回避するための戦略を学びました。
最後に、NumberFormatExceptionに対処するためのいくつかのベストプラクティスを見ました。
いつものように、例で使用されているソースコードは、GitHubのにあります。