Integer.parseInt(String, int) にご注意
0xFFFFFFFF は 32 bit int で、型が符号付きなら -1 です。
Java は符号なし int はないので、常に -1 なのですが、ちょっとした罠があります。
以下は文字列 "FFFFFFFF" を int に直そうとするコードです。これを実行するとどうなるでしょう。
public class ParseIntTest { public static void main(String[] args) { int num = Integer.parseInt("FFFFFFFF", 16); System.out.println(num); } }
なんと、NumberFormatException が発生します。10 年以上 Java やってますが、知りませんでした。
Exception in thread "main" java.lang.NumberFormatException: For input string: "FFFFFFFF" at java.lang.NumberFormatException.forInputString(Unknown Source) at java.lang.Integer.parseInt(Unknown Source) at ParseIntTest.main(ParseIntTest.java:3)
Javadoc の Integer.parseInt(String, int) には、
例外:
NumberFormatException - String が構文解析可能な int 値を含まない場合
Integer (Java 2 Platform SE 5.0)
という説明だけしか書かれておらず、今回の文字列が不正であることが明示的には記載されていません。推測するに、"FFFFFFFF" が符号なし換算で Integer.MAX_VALUE を超えているから、ということだとは思いますが。
なお、以下のコードは全く問題ありません。
public class ParseIntTest { public static void main(String[] args) { int num = 0xFFFFFFFF; System.out.println(num); } }
parseInt なんだから、"FFFFFFFF" は int の -1 にしてもらいたいものです。
Android(Dalvik、Harmony)ではどうかというと、
java.lang.NumberFormatException: Invalid int: "FFFFFFFF" at java.lang.Integer.invalidInt(Integer.java:138) at java.lang.Integer.parse(Integer.java:378) at java.lang.Integer.parseInt(Integer.java:366)
メッセージこそ違いますが、NumberFormatException が出ることには変わりがないようです。
さて、ではどうすればよいか、というと、このケースでは Long.parseLong(String, int) を使用すれば回避できます。
public class ParseIntTest { public static void main(String[] args) { int num = (int) Long.parseLong("FFFFFFFF", 16); System.out.println(num); } }
8 桁の 16 進数文字列を int に変換する場合、場合によっては失敗する、ということを頭の片隅に置いておきましょう。