2011-07-12 127 views
2

我在分析一個字符串轉換爲字節爲什麼Java的拋出NumberFormatException異常

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]); 
} 
+1

當你打印的價值'st'你看到了什麼? –

回答

5

這是因爲默認的解析方法預計十進制格式的數字,來分析十六進制數,使用此parse

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

其中16是解析的基礎。

至於你的評論,你是對的。字節的最大值是0x7F。所以,你可以解析它作爲int0xff執行二進制與操作來獲得LSB,這是你的字節:

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

更改後但得到此異常java.lang.NumberFormatException:值超出範圍。值:「9B」基數:16 –

+0

你是rught - 字節是一個有符號的類型,它的最大值是0x7F。因爲整數足夠大並且允許二進制操作,所以使用以下代替'bytes [i] = Integer.parseInt(st [i],16)& 0xFF;'。 – MByD

5

假設你要解析字符串爲十六進制有一個例外,試試這個:

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

默認的基數是10 ,而且顯然B不是以10爲底的數字。

+0

更改後但得到此異常java.lang.NumberFormatException:值超出範圍。值:「9B」基數:16 –

0

Java是在符號性非常挑剔,也不會接受值溢出。因此,如果你解析一個字節並且它大於127(例如,130十進制或83十六進制),你將得到一個NumberFormatException異常。如果將8位十六進制數字解析爲整數(或16位十六進制數字作爲長整數)並且以8-F開頭,則會發生同樣的情況。這些值不會被解釋爲負數(二的補碼),但是不合法。

如果您認爲這是肛門保留型,我完全同意。但這是Java風格。

要將十六進制值解析爲二進制補碼數字,請使用足夠大的整數類型(例如,如果您正在解析字節,則使用Integer並在稍後將其轉換爲字節),或者 - 如果需要解析長,將數字分成一半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); 
} 

或者讀一個字節,只需使用整數代替:

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; 
} 
相關問題