Compreendendo a NumberFormatException em Java

Compreendendo a NumberFormatException em Java

1. Introdução

Java lançaNumberFormatException –an unchecked exception - quando não podeconvert a String to a number type.

Como éunchecked, Java não nos força a manipulá-lo ou declará-lo.

Neste tutorial rápido, descreveremos e demonstraremoswhat causes NumberFormatException in Java and how to avoid or deal with it.

2. Causas deNumberFormatException

Existem vários problemas que causamNumberFormatException. Por exemplo, alguns construtores e métodos em Java lançam essa exceção.

Discutiremos a maioria deles nas seções abaixo.

2.1. Dados não numéricos passados ​​para o construtor

Vejamos uma tentativa de construir um objetoInteger ouDouble com dados não numéricos.

Ambas as instruções geramNumberFormatException:

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

Vamos ver o rastreamento de pilha que obtivemos quando passamos a entrada inválida “um” para o construtorInteger na linha 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)

Ele lançouNumberFormatException. O construtorInteger falhou ao tentar entender a entrada usandoparseInt() internamente.

A Java Number API não converte palavras em números, então podemos corrigir o código simplesmente alterando-o para um valor esperado:

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

2.2. Análise de strings contendo dados não numéricos

Semelhante ao suporte do Java para análise no construtor, temos métodos de análise dedicados comoparseInt(), parseDouble(),valueOf() edecode().

Se tentarmos fazer os mesmos tipos de conversão com estes:

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

Então, veremos o mesmo tipo de comportamento errôneo.

E podemos corrigi-los de maneiras semelhantes:

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

2.3. Passando cordas com caracteres estranhos

Ou, se tentarmos converter uma string em um número comextraneous data in input, like whitespace or special characters:

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

Então, teremos o mesmo problema de antes.

Nós podemos corrigi-los com um pouco de manipulação de string:

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

Observe aqui na linha 3 quenegative numbers are allowed, usando o caractere hífen como sinal de menos.

2.4. Formatos de número específicos da localidade

Vejamos um caso especial de números específicos de localidade. Nas regiões europeias, uma vírgula pode representar uma casa decimal. Por exemplo, "4000,1" pode representar o número decimal "4000.1".

Por padrão, obteremosNumberFormatException tentando analisar um valor que contém uma vírgula:

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

Precisamos permitir vírgulas e evitar a exceção neste caso. Para tornar isso possível, o Java precisa entender a vírgula aqui como um decimal.

Podemos permitir vírgulas para a região europeia e evitar a exceção usandoNumberFormat.

Vamos ver isso em ação usandoLocale para a França como exemplo:

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

3. Melhores Práticas

Vamos falar sobre algumas boas práticas que podem nos ajudar a lidar comNumberFormatException:

  1. Don’t try to convert alphabetic or special characters into numbers - o Java Number API não pode fazer isso.

  2. Podemos querervalidate an input string using regular expressions and throw the exception for the invalid characters.

  3. Podemos limpar a entrada de problemas conhecidos previsíveis com métodos comotrim()ereplaceAll().

  4. Em alguns casos, caracteres especiais na entrada podem ser válidos. Então, fazemos um processamento especial para isso, usandoNumberFormat, por exemplo, que suportanumerous formats.

4. Conclusão

Neste tutorial, discutimosNumberFormatException em Java e o que o causa. Entender essa exceção pode nos ajudar a criar aplicativos mais robustos.

Além disso, aprendemos estratégias para evitar a exceção com algumas seqüências de entrada inválidas.

Finalmente, vimos algumas práticas recomendadas para lidar comNumberFormatException.

Como de costume, o código-fonte usado nos exemplos pode ser encontradoover on GitHub.