java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

文字列を数値に変換する

投稿日:

最終更新日:2016年07月06日

アイキャッチ

こんにちは。「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型なので当然ではあるのですが。最初読んだときは何のことなのかわかりませんでした。