Por que Java lança um NumberFormatException

Eu tenho uma exceção ao analisar uma string para 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]); } 

Isso porque o método de análise padrão espera um número no formato decimal, para analisar o número hexadecimal, use essa análise :

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

Onde 16 é a base para a análise.

Quanto ao seu comentário, você está certo. O valor máximo de Byte é 0x7F. Então você pode analisá-lo como int e executar a operação binária AND com 0xff para obter o LSB, que é seu byte:

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

Supondo que você queira analisar a string como hexadecimal, tente isto:

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

A raiz padrão é 10 e, obviamente, B não é uma base de 10 dígitos.

Java é muito exigente em sinalização, não aceita valores para overflow. Portanto, se você analisar um byte e ele for maior que 127 (por exemplo, 130 dec ou 83 hex), você receberá um NumberFormatException. O mesmo acontece se você analisar um número hexadecimal de 8 dígitos como um Integer (ou um número hexadecimal de 16 dígitos como Long) e começar com 8-F. Esses valores não serão interpretados como negativos (complemento de dois), mas como ilegais.

Se você acha que isso é um retentivo anal, eu concordo totalmente. Mas esse é o estilo Java.

Para analisar valores hexadecimais como os números de complemento de dois, use um tipo inteiro grande o suficiente (por exemplo, se estiver analisando um byte use Integer e digite-o em um byte mais tarde) ou – se precisar analisar um Long, divida o número na metade é 16 dígitos, em seguida, combinar. Aqui está um exemplo:

 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); } 

Ou, para ler um byte, basta usar 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; }