为什么Java会抛出NumberFormatException

时间:2011-07-12 00:50:50

标签: java exception

将字符串解析为byte

时出现异常
String Str ="9B7D2C34A366BF890C730641E6CECF6F";

String [] st=Str.split("(?<=\\G.{2})");

byte[]bytes = new byte[st.length];
for (int i = 0; i <st.length; i++) {
 bytes[i] = Byte.parseByte(st[i]);
}

3 个答案:

答案 0 :(得分:5)

假设您要将字符串解析为十六进制,请尝试:

bytes[i] = Byte.parseByte(st[i], 16);

默认基数为10,显然B不是10位数。

答案 1 :(得分:5)

那是因为默认的解析方法需要十进制格式的数字,要解析十六进制数,请使用parse

Byte.parseByte(st[i], 16);

其中16是解析的基础。

至于你的评论,你是对的。字节的最大值为0x7F。因此,您可以将其解析为int并使用0xff执行二进制AND操作以获取LSB,即您的字节:

bytes[i] = Integer.parseInt(st[i], 16) & 0xFF;

答案 2 :(得分:0)

Java对签名非常挑剔,它不会接受溢出的值。因此,如果您解析一个Byte并且它大于127(例如,130 dec或83 hex),您将得到NumberFormatException。如果您将8位十六进制数字解析为整数(或16位十六进制数字作为Long)并且以8-F开头,则会发生相同的情况。这些值不会被解释为负数(二进制补码),而是非法的。

如果您认为这是肛门保留,我完全同意。但那是Java风格。

要将十六进制值解析为二进制补码数,要么使用足够大的整数类型(例如,如果要解析字节,请使用Integer,然后键入将其转换为字节)或者 - 如果需要解析long ,将数字分成两半,即16位数,然后合并。这是一个例子:

public static long longFromHex(String s) throws IllegalArgumentException {
    if (s.length() == 16)
        return (Long.parseLong(s.substring(0,8),16)<<32)|(Long.parseLong(s.substring(8,16),16)&0xffffffffL);
    return Long.parseLong(s, 16);
}

或者,要读取字节,只需使用Integer:

public static byte byteFromHex(String s) throws IllegalArgumentException {
    int i = Integer.parseInt(s, 16);
    if (i < 0 || i > 255) throw new IllegalArgumentException("input string "+s+" does not fit into a Byte");
    return (byte)i;
}