почему Java генерирует NumberFormatException - PullRequest
2 голосов
/ 12 июля 2011

Возникла исключительная ситуация при разборе строки на байт

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 ]

5 голосов
/ 12 июля 2011

Это потому, что метод синтаксического анализа по умолчанию ожидает число в десятичном формате. Для анализа шестнадцатеричного числа используйте это parse :

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

Где 16 - основа для синтаксического анализа.

Что касается вашего комментария, вы правы.Максимальное значение байта 0x7F.Таким образом, вы можете проанализировать его как int и выполнить двоичную операцию И с 0xff, чтобы получить младший бит, который является вашим байтом:

bytes[i] = Integer.parseInt(st[i], 16) & 0xFF;
5 голосов
/ 12 июля 2011

Предполагая, что вы хотите проанализировать строку как шестнадцатеричное, попробуйте это:

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

Значение по умолчанию равно 10, и, очевидно, B не является основанием из 10 цифр.

0 голосов
/ 24 октября 2013

Java очень требовательна к подписи, она не будет принимать значения для переполнения.Таким образом, если вы анализируете байт и он больше 127 (например, 130 dec или 83 hex), вы получите исключение NumberFormatException.То же самое происходит, если вы анализируете 8-значное шестнадцатеричное число как целое число (или 16-значное шестнадцатеричное число как длинное), и оно начинается с 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...