Перейти к содержимому

Numberformatexception java что это

  • автор:

NumberFormatException при считывании чисел из файла

Вылетает ошибка NumberFormatException .
При работе с консолью всё работает нормально. Считывает он вроде то что нужно:

public static void main(String[] args) throws IOException < BufferedReader reader1 = new BufferedReader(new InputStreamReader(System.in)); String name = reader1.readLine(); BufferedReader reader = new BufferedReader(new FileReader(name)); String buf = ""; try < while (reader.ready()) < buf = reader.readLine(); System.out.println(Integer.parseInt(buf)); >> catch (Exception e) < System.out.println("Мы считали: " + buf); >> 

Мы считали: 32

Где ошибка?
Отслеживать
19.1k 6 6 золотых знаков 30 30 серебряных знаков 44 44 бронзовых знака
задан 19 фев 2017 в 12:49
125 2 2 серебряных знака 9 9 бронзовых знаков

В stacktrace у NumberFormatException указывается строка, которая приводит к появлению исключения. Проанализируйте её, а также добавьте stacktrace в вопрос.

19 фев 2017 в 13:27

Exception in thread «main» java.lang.NumberFormatException: For input string: «32». Не знаю как добавить это в вопрос

19 фев 2017 в 16:47

В нижней части вопроса, чуть ниже меток, есть кнопка «Править». Нажмите на неё и добавьте весь stacktrace в конец текста вопроса.

19 фев 2017 в 16:54

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Ошибка возникает, скорее всего, из-за того, что после числа идет пробел или какой-то другой подобный символ. Есть предложение: после считывания строки вызвать для неё метод trim() . Этот метод удаляет пробелы в начале и конце строки.

Тогда парсинг будет выглядеть так:

Integer.parseInt(buf.trim()) 

Отслеживать
19.1k 6 6 золотых знаков 30 30 серебряных знаков 44 44 бронзовых знака
ответ дан 19 фев 2017 в 12:55
15k 1 1 золотой знак 22 22 серебряных знака 40 40 бронзовых знаков
trim() не помог. При выводе в консоль buf выводится без пробелов и переносов
19 фев 2017 в 16:51

Если метод trim не справляется с задачей (в частности, он удаляет только символы с кодами от 0 до 32 включительно и только из начала и конца строки), то справиться может replaceAll :

buf = buf.replaceAll("[^0-9]", ""); 

Который удалит из строки все символы, не являющиеся цифрами.

Чтобы выяснить какие же символы содержатся в строке, можно воспользоваться таким методом:

private static void displayChars(String str) < for (int i = 0; i < str.length(); i++) < System.out.print((int)str.charAt(i) + " "); >> 

Если System.out.println(«Мы считали: » + buf); заменить на displayChars(buf); , то должно стать понятно что же за символы «портят жизнь».

Таким символом может оказаться 65279 (то есть BOM), находящий в самом начале файла.

Numberformatexception java что это

08.01.2024 г.

Извините, но для просмотра этой страницы у Вас недостаточно прав.
Вы должны авторизоваться или пройти регистрацию.
Авторизоваться можно на главной странице

© 2024 Программирование — это просто

Joomla! — свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru — Русский Дом Joomla!

Понимание исключения NumberFormatException в Java

Поскольку он не отмечен , Java не заставляет нас обрабатывать или объявлять его.

В этом кратком руководстве мы опишем и продемонстрируем , что вызывает исключение NumberFormatException в Java и как его избежать или справиться с ним .

2. Причины исключения NumberFormatException ​

Существуют различные проблемы, вызывающие NumberFormatException . Например, некоторые конструкторы и методы в Java вызывают это исключение.

Мы обсудим большинство из них в разделах ниже.

2.1. Нечисловые данные, переданные конструктору

Давайте рассмотрим попытку создания объекта Integer или Double с нечисловыми данными.

Оба этих утверждения вызовут NumberFormatException :

 Integer aIntegerObj = new Integer("one");   Double doubleDecimalObj = new Double("two.2"); 

Давайте посмотрим на трассировку стека, которую мы получили, когда передали неверный ввод «один» конструктору Integer в строке 1:

 Exception in thread "main" java.lang.NumberFormatException: For input string: "one"   at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)   at java.lang.Integer.parseInt(Integer.java:580)   at java.lang.Integer.init>(Integer.java:867)   at MainClass.main(MainClass.java:11) 

Он выдал NumberFormatException . Конструктор Integer потерпел неудачу при попытке понять ввод с помощью parseInt() внутренне.

Java Number API не преобразует слова в числа, поэтому мы можем исправить код, просто изменив его на ожидаемое значение:

 Integer aIntegerObj = new Integer("1");   Double doubleDecimalObj = new Double("2.2"); 

2.2. Разбор строк, содержащих нечисловые данные

Подобно поддержке синтаксического анализа в конструкторе в Java, у нас есть специальные методы синтаксического анализа, такие как par seInt(), parseDouble(), valueOf() и decode() .

Если мы попытаемся сделать те же самые виды преобразования с ними:

 int aIntPrim = Integer.parseInt("two");   double aDoublePrim = Double.parseDouble("two.two");   Integer aIntObj = Integer.valueOf("three");   Long decodedLong = Long.decode("64403L"); 

Тогда мы увидим такое же ошибочное поведение.

И мы можем исправить их аналогичным образом:

 int aIntPrim = Integer.parseInt("2");   double aDoublePrim = Double.parseDouble("2.2");   Integer aIntObj = Integer.valueOf("3");   Long decodedLong = Long.decode("64403"); 

2.3. Передача строк с посторонними символами

Или, если мы попытаемся преобразовать строку в число с посторонними данными на входе, такими как пробелы или специальные символы:

 Short shortInt = new Short("2 ");   int bIntPrim = Integer.parseInt("_6000"); 

Тогда у нас будет та же проблема, что и раньше.

Мы могли бы исправить это, немного поработав со строками:

 Short shortInt = new Short("2 ".trim());   int bIntPrim = Integer.parseInt("_6000".replaceAll("_", ""));   int bIntPrim = Integer.parseInt("-6000"); 

Обратите внимание, что здесь, в строке 3, допускаются отрицательные числа , используя символ дефиса в качестве знака минус.

2.4. Форматы чисел, зависящие от локали

Давайте рассмотрим частный случай номеров, зависящих от локали. В европейских регионах запятая может обозначать десятичный разряд. Например, «4000,1» может представлять десятичное число «4000,1».

По умолчанию мы получим NumberFormatException , пытаясь разобрать значение, содержащее запятую:

 double aDoublePrim = Double.parseDouble("4000,1"); 

Нам нужно разрешить запятые и избежать исключения в этом случае. Чтобы сделать это возможным, Java должна понимать запятую здесь как десятичную.

Мы можем разрешить запятые для европейского региона и избежать исключения, используя NumberFormat .

Давайте посмотрим на это в действии, используя Locale для Франции в качестве примера:

 NumberFormat numberFormat = NumberFormat.getInstance(Locale.FRANCE);   Number parsedNumber = numberFormat.parse("4000,1");   assertEquals(4000.1, parsedNumber.doubleValue());   assertEquals(4000, parsedNumber.intValue()); 

3. Лучшие практики​

Давайте поговорим о нескольких хороших практиках, которые могут помочь нам справиться с NumberFormatException :

  1. Не пытайтесь преобразовать буквенные или специальные символы в числа — Java Number API не может этого сделать.
  2. Мы можем захотеть проверить входную строку с помощью регулярных выражений и выдать исключение для недопустимых символов .
  3. Мы можем дезинфицировать ввод от предсказуемых известных проблем с помощью таких методов, как trim() и replaceAll() .
  4. В некоторых случаях допустимы вводимые специальные символы. Поэтому мы делаем для этого специальную обработку, например, с помощью NumberFormat , который поддерживает множество форматов .

4. Вывод​

В этом руководстве мы обсудили исключение NumberFormatException в Java и его причины. Понимание этого исключения может помочь нам создавать более надежные приложения.

Кроме того, мы научились избегать исключений с некоторыми недопустимыми входными строками.

Наконец, мы увидели несколько лучших практик для работы с NumberFormatException .

Как обычно, исходный код, использованный в примерах, можно найти на GitHub .

  • 1. Введение
  • 2. Причины исключения NumberFormatException
    • 2.1. Нечисловые данные, переданные конструктору
    • 2.2. Разбор строк, содержащих нечисловые данные
    • 2.3. Передача строк с посторонними символами
    • 2.4. Форматы чисел, зависящие от локали

    Обработка исключений. Проверяемые и непроверяемые исключения

    Рассмотрим метод Integer.parseInt(String) , который принимает число в форме строки (например, «94» , «865» ) и возвращает его целочисленное представление (например, 94 , 865 ).

    Очевидно, что Integer.parseInt(«650») == 650 , а Integer.parseInt(«-1») == -1 . Но чему равно выражение Integer.parseInt(«surprise») ? Нулю? Это было бы ужасно, такую ошибку невозможно было бы отловить. Сумме числовых значений всех букв? Ещё хуже.

    Метод parseInt не может вернуть числовое значение строки «surprise», в десятичной системе есть только цифры 0..9 , эта задача невыполнима. Метод выбрасывает исключение.

    Выброс исключения прерывает выполнение метода, если его никто не ловит. В примере оно выбрасывается из метода parseInt(String s, int radix) , затем прерывает метод parseInt(String s) , затем — main . В консоль будет выведена трассировка стека вызовов (stack trace) — это список методов, которые были вызваны, c именами файлов и номерами строк, в которых это произошло.

    Exception in thread "main" java.lang.NumberFormatException: For input string: "surprise" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.parseInt(Integer.java:615) at online.javanese.basics.oop.exceptions.ParseInt.main(ParseInt.java:6)

    Если в данном контексте вы не можете ничего сделать с исключением — не ловите его, пусть программа падает. Если же вы можете как-то восстановиться после исключения, можно его поймать:

    package online.javanese.basics.oop.exceptions; public class ParseInt < public static void main(String[] args) < try < Integer.parseInt("surprise"); >catch (NumberFormatException e) < System.out.println("Так себе число."); >> >

    В блоке try выполняются действия, которые могут привести к исключению. Если исключение не будет выброшено, блок catch будет проигнорирован. Если же любой код, выполняющийся внутри try , выбрасывает исключение подходящего типа (в данном случае — NumberFormatException ), управление передаётся блоку catch . Если выброшено исключение неподходящего класса, оно не попадает в catch .

    Непроверяемые исключения

    Иерархия исключений, наследующих RuntimeException , предполагает, что ошибка в нахдится коде, т. е. в ней виновен программист. Следовательно, восстановить выполнение программы не удастся, нужно исправлять ошибку в коде, поэтому и ловить такие исключения не нужно. Вот основные представители:

    int[] zeroSizeArray = new int[0]; int firstItem = zeroSizeArray[0]; // ArrayIndexOutOfBoundsException zeroSizeArray[0] = 200700; // ArrayIndexOutOfBoundsException int lol = 10 / 0; // ArithmeticException int numberFromString = Integer.parseInt("not a number"); // NumberFormatException

    Проверяемые исключения

    Проверяемые исключения (checked exceptions) — такие исключения, которые необходимо ловить. Их возникновение — это штатная ситуация. Например, посчитаем отпечаток пароля с помощью алгоритма SHA-512 и выведем его как массив байт. Это удастся сделать, только если на данном компьютере доступен этот алгоритм.

    План А: перебрасываем

    try < MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); System.out.println(Arrays.toString(sha512.digest("password".getBytes()))); >catch (NoSuchAlgorithmException e) < // если SHA-512 не поддерживается, // выполнить задачу невозможно — падаем, // бросая непроверяемое исключение, // в качестве причины которого указываем пойманное: throw new RuntimeException(e); >
    [-79, 9, -13, -69, -68, 36, 78, -72, 36, 65, -111, 126, -48, 109, 97, -117, -112, 8, -35, 9, -77, -66, -3, 27, 94, 7, 57, 76, 112, 106, -117, -71, -128, -79, -41, 120, 94, 89, 118, -20, 4, -101, 70, -33, 95, 19, 38, -81, 90, 46, -90, -47, 3, -3, 7, -55, 83, -123, -1, -85, 12, -84, -68, -122]

    Неудача, алгоритм недоступен:

    Exception in thread "main" java.lang.RuntimeException: java.security.NoSuchAlgorithmException: SHA-512 MessageDigest not available at online.javanese.basics.oop.exceptions.Sha512.main(Sha512.java:14) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) Caused by: java.security.NoSuchAlgorithmException: SHA-512 MessageDigest not available at sun.security.jca.GetInstance.getInstance(GetInstance.java:159) at java.security.Security.getImpl(Security.java:695) at java.security.MessageDigest.getInstance(MessageDigest.java:167) at online.javanese.basics.oop.exceptions.Sha512.main(Sha512.java:11) . 5 more

    План Б: восстанавливаемся

    try < MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); System.out.println(Arrays.toString(sha512.digest("password".getBytes()))); >catch (NoSuchAlgorithmException e) < System.out.println("SHA-512 недоступен. ¯\\_(ツ)_/¯"); >

    Успех выглядит так же. Неудача:

    SHA-512 недоступен. ¯\_(ツ)_/¯

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *