こんにちは。「Javaを復習する初心者」です。
最近はStringのAPI仕様ばかり見ていたのですが、ふと文字列としての数値を整数に直す方法が気になり、Integer#parseInt()を調べました。このメソッドはstaticなのでインスタンスの生成なしで使うことができます。
parseIntは次の2つがあります。
- static int parseInt(String s)
- static int parseInt(String s, int radix)
parseInt(String s)は10進数変換です。parseInt(String s, int radix)はradixを基数にしてsを変換します。parseInt(String s)は内部でparseInt(s, 10)を呼び出してます。今回扱うのはparseInt(String s, int radix)です。
正常系
まず正常系を実験しました。以下はソースと実行結果です。
ソースコード
package integerTest;
public class HelloParseIntNormal {
public static void main(String[] args) {
System.out.println(Integer.parseInt("Z", 36));
System.out.println(Integer.parseInt("+1", 36));
System.out.println(Integer.parseInt("-2", 36));
}
}
結果
35
1
-2
上記のプログラムはエラーなしで結果が出ます。まず基数は2から35まで使えます。35進数で「Z」は10進数で「35」ということです。文字列の先頭にはプラスマイナス記号が使えます。プラス記号がない場合は、正の整数として扱われるようです。
異常系
public static int parseInt(String s, int radix)のソースを見るとNumberFormatExceptionをスローしている個所があります。次のプログラムは各々の箇所を通過するパターンを書いたものです。
ソースコード
package integerTest;
public class HelloParseIntError {
public static void main(String[] args) {
System.out.println("nullの場合");
try {
System.out.println(Integer.parseInt(null, 16));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("基数を1に指定");
try {
System.out.println(Integer.parseInt("100", 1));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("基数を37に指定");
try {
System.out.println(Integer.parseInt("100", 37));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("「.」など+-以外の記号");
try {
System.out.println(Integer.parseInt("."));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("+-どちらかのみ");
try {
System.out.println(Integer.parseInt("+"));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("空文字の場合");
try {
System.out.println(Integer.parseInt(""));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("基数2で途中で3が登場");
try {
System.out.println(Integer.parseInt("123", 2));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("2147483647を超える");
try {
System.out.println(Integer.parseInt("2147483648", 10));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
System.out.println("2147483647より桁が大きい");
try {
System.out.println(Integer.parseInt("21474836470", 10));
} catch (Exception e) {
e.printStackTrace();
System.out.println();
}
}
}
結果
nullの場合
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:9)
基数を1に指定
java.lang.NumberFormatException: radix 1 less than Character.MIN_RADIX
at java.lang.Integer.parseInt(Integer.java:546)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:17)
基数を37に指定
java.lang.NumberFormatException: radix 37 greater than Character.MAX_RADIX
at java.lang.Integer.parseInt(Integer.java:551)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:25)
「.」など+-以外の記号
java.lang.NumberFormatException: For input string: "."
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:569)
at java.lang.Integer.parseInt(Integer.java:615)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:33)
+-どちらかのみ
java.lang.NumberFormatException: For input string: "+"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:572)
at java.lang.Integer.parseInt(Integer.java:615)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:41)
空文字の場合
java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:592)
at java.lang.Integer.parseInt(Integer.java:615)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:49)
基数2で途中で3が登場
java.lang.NumberFormatException: For input string: "123"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:57)
2147483647を超える
java.lang.NumberFormatException: For input string: "2147483648"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:587)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:65)
2147483647より桁が大きい
java.lang.NumberFormatException: For input string: "21474836470"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:583)
at integerTest.HelloParseIntError.main(HelloParseIntError.java:73)
API仕様書に例外がスローされる条件は書いてあるので参考にしたのですが、最後の方は勘でやりました。API仕様書に挙げられている「文字列によって表される値が、int型の値ではない。 」は上記プログラムの最後2つのパターンのことだと思います。long型には変換できないということなのでしょう。返却値がint型なので当然ではあるのですが。最初読んだときは何のことなのかわかりませんでした。