Разбиране на NumberFormatException в Java

1. Въведение

Java хвърля NumberFormatException - непроверено изключение - когато не може да преобразува String в числов тип.

Тъй като е отметнато, Java не ни принуждава да го обработваме или декларираме.

В този бърз урок ще опишем и покажем какво причинява NumberFormatException в Java и как да го избегнем или да се справим с него .

2. Причини за NumberFormatException

Има различни проблеми, които причиняват NumberFormatException . Например някои конструктори и методи в Java хвърлят това изключение.

Ще обсъдим повечето от тях в секциите по-долу.

2.1. Нецифрени данни, предадени на конструктора

Нека разгледаме опит за изграждане на цяло число или двоен обект с нецифрени данни.

И двете изявления ще хвърлят NumberFormatException :

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

Нека видим трасето на стека, което получихме, когато предадохме невалиден вход „one“ на конструктора 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.(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.