Tenho um projeto no qual costumamos usar Integer.parseInt()
para converter uma String em um int. Quando algo dá errado (por exemplo, o String
não é um número, mas a letra a
ou o que quer que seja), esse método lançará uma exceção. No entanto, se eu tiver que lidar com exceções em meu código em todos os lugares, isso começa a ficar muito feio muito rapidamente. Gostaria de colocar isso em um método, no entanto, não tenho ideia de como retornar um valor limpo para mostrar que a conversão deu errado.
Em C ++, eu poderia ter criado um método que aceitasse um ponteiro para um int e deixasse o próprio método retornar verdadeiro ou falso. No entanto, até onde eu sei, isso não é possível em Java. Eu também poderia criar um objeto que contenha uma variável verdadeiro / falso e o valor convertido, mas isso também não parece ideal. A mesma coisa vale para um valor global, e isso pode me dar alguns problemas com multithreading.
Então, há uma maneira limpa de fazer isso?
fonte
int
enquanto 2147483648 não é.Respostas:
Você poderia retornar um em
Integer
vez de umint
, retornandonull
na falha de análise.É uma pena que o Java não forneça uma maneira de fazer isso sem que haja uma exceção lançada internamente - você pode ocultar a exceção (capturando-a e retornando nulo), mas ainda pode ser um problema de desempenho se você estiver analisando centenas de milhares de bits de dados fornecidos pelo usuário.
EDIT: Código para tal método:
Observe que não tenho certeza de início do que isso fará se
text
for nulo. Você deve considerar que - se representar um bug (ou seja, seu código pode muito bem passar um valor inválido, mas nunca deve passar nulo), então lançar uma exceção é apropriado; se não representar um bug, você provavelmente deve retornar nulo como faria para qualquer outro valor inválido.Originalmente, essa resposta usava o
new Integer(String)
construtor; agora usaInteger.parseInt
uma operação de boxe; desta forma, pequenos valores acabarão sendo encaixotados emInteger
objetos em cache , tornando-o mais eficiente nessas situações.fonte
null
referências do que lidar com exceções regularmente.Que comportamento você espera quando não é um número?
Se, por exemplo, você costuma ter um valor padrão para usar quando a entrada não é um número, um método como este pode ser útil:
Métodos semelhantes podem ser escritos para diferentes comportamentos padrão quando a entrada não pode ser analisada.
fonte
Em alguns casos, você deve lidar com erros de análise como situações de falha rápida, mas em outros casos, como configuração de aplicativo, prefiro lidar com a entrada ausente com valores padrão usando Apache Commons Lang 3 NumberUtils .
fonte
Para evitar o tratamento de exceções, use uma expressão regular para garantir que você tenha todos os dígitos primeiro:
fonte
Existe
Ints.tryParse()
na Goiaba . Ele não lança exceção em uma string não numérica, no entanto, ele lança uma exceção em uma string nula.fonte
Depois de ler as respostas à pergunta, acho que encapsular ou envolver o método parseInt não é necessário, talvez até não seja uma boa ideia.
Você poderia retornar 'nulo' como Jon sugeriu, mas isso é mais ou menos substituindo uma construção try / catch por uma verificação de nulo. Há apenas uma pequena diferença no comportamento se você 'esquecer' o tratamento de erros: se você não capturar a exceção, não há atribuição e a variável do lado esquerdo mantém o valor antigo. Se você não testar o valor nulo, provavelmente será atingido pelo JVM (NPE).
A sugestão do yawn me parece mais elegante, porque não gosto de retornar null para sinalizar alguns erros ou estados excepcionais. Agora você tem que verificar a igualdade referencial com um objeto predefinido, que indica um problema. Mas, como outros argumentam, se novamente você 'esquecer' de verificar e uma String não puder ser analisada, o programa continuará com o int dentro do seu objeto 'ERROR' ou 'NULL'.
A solução de Nikolay é ainda mais orientada a objetos e também funcionará com métodos parseXXX de outras classes de wrapper. Mas, no final, ele apenas substituiu NumberFormatException por uma exceção OperationNotSupported - mais uma vez, você precisa de um try / catch para lidar com entradas não analisáveis.
Portanto, minha conclusão é não encapsular o método parseInt simples. Eu apenas encapsularia se pudesse adicionar também algum tratamento de erros (dependente do aplicativo).
fonte
Pode ser que você possa usar algo assim:
fonte
Você também pode replicar o comportamento C ++ que deseja de forma muito simples
Você usaria o método assim:
Depois disso, a variável
result
é verdadeira se tudo correr bem ebyRef[0]
contiver o valor analisado.Pessoalmente, eu me limitaria a pegar a exceção.
fonte
A resposta dada por Jon Skeet é boa, mas eu não gosto de devolver um
null
objeto Integer. Acho isso confuso de usar. Desde Java 8 existe uma opção melhor (na minha opinião), usando oOptionalInt
:Isso torna explícito que você deve lidar com o caso em que nenhum valor está disponível. Eu preferiria que esse tipo de função fosse adicionado à biblioteca java no futuro, mas não sei se isso acontecerá.
fonte
Se estiver usando Java 8 ou superior, você pode usar uma biblioteca que acabei de lançar: https://github.com/robtimus/try-parse . Ele tem suporte para int, long e boolean que não depende da captura de exceções. Ao contrário do Ints.tryParse do Guava, ele retorna OptionalInt / OptionalLong / Optional, bem como em https://stackoverflow.com/a/38451745/1180351, mas mais eficiente.
fonte
Meu Java está um pouco enferrujado, mas deixe-me ver se posso indicar a direção certa:
Se o seu valor de retorno for
null
, você tem um valor ruim. Caso contrário, você tem um válidoInteger
.fonte
Integer.tryParse
naInteger
classe Java padrão . 2. Fazernew Integer
é desnecessário (e não recomendado), pois Java faz boxing e unboxing automaticamente. Seu Java não está apenas um pouco enferrujado, está muito enferrujado.E quanto ao método parseInt ?
É fácil, basta copiar e colar o conteúdo em um novo utilitário que retorna
Integer
ouOptional<Integer>
e substitui lança por retorna. Parece que não há exceções no código subjacente, mas é melhor verificar .Ao pular todo o material de tratamento de exceções, você pode economizar algum tempo com entradas inválidas. E o método existe desde o JDK 1.0, portanto, não é provável que você precise fazer muito para mantê-lo atualizado.
fonte
Eu sugiro que você considere um método como
que você então implementa conforme achar adequado. Se você quiser que o resultado volte - talvez porque você usa Integer.parseInt () de qualquer maneira - você pode usar o truque do array.
onde você define result [0] para o valor inteiro encontrado no processo.
fonte
Isso é um pouco semelhante à solução de Nikolay:
O método principal demonstra o código. Outra forma de implementar a interface do Parser seria obviamente apenas definir "\ D +" da construção e fazer com que os métodos não fizessem nada.
fonte
Você pode rolar o seu próprio, mas é tão fácil de usar o
StringUtils.isNumeric()
método de commons lang . Ele usa Character.isDigit () para iterar sobre cada caractere na String.fonte
A maneira como lido com esse problema é recursivamente. Por exemplo, ao ler dados do console:
fonte
Para evitar uma exceção, você pode usar o
Format.parseObject
método Java . O código abaixo é basicamente uma versão simplificada da classe IntegerValidator do Apache Common .Você pode usar
AtomicInteger
ou oint[]
truque da matriz, dependendo de sua preferência.Aqui está o meu teste que o usa -
fonte
Eu também estava tendo o mesmo problema. Este é um método que escrevi para pedir uma entrada ao usuário e não aceitar a entrada a menos que seja um inteiro. Por favor, note que eu sou um iniciante, então se o código não estiver funcionando como esperado, culpe minha inexperiência!
fonte
Esta é uma resposta à pergunta 8391979, "O java tem um int.tryparse que não lança uma exceção para dados inválidos? [Duplicado]", que está fechado e vinculado a esta pergunta.
Editar 2016 08 17: Métodos ltrimZeroes adicionados e chamados em tryParse (). Sem zeros à esquerda em numberString pode dar resultados falsos (veja os comentários no código). Agora existe também o método público estático String ltrimZeroes (String numberString) que funciona para "números" positivos e negativos (END Edit)
Abaixo você encontra uma classe Wrapper (boxing) rudimentar para int com um método tryParse () otimizado de alta velocidade (semelhante ao C #) que analisa a própria string e é um pouco mais rápido do que Integer.parseInt (String s) do Java:
Teste / programa de exemplo para a classe IntBoxSimple:
fonte
Tente com expressão regular e argumento de parâmetros padrão
se você estiver usando apache.commons.lang3, use NumberUtils :
fonte
Eu gostaria de apresentar outra proposta que funciona se alguém solicitar números inteiros especificamente: Basta usar long e Long.MIN_VALUE para casos de erro. Isso é semelhante à abordagem que é usada para chars em Reader, onde Reader.read () retorna um inteiro no intervalo de um char ou -1 se o leitor estiver vazio.
Para Float e Double, o NaN pode ser usado de maneira semelhante.
fonte
Considerando as respostas existentes, copiei e melhorei o código-fonte do
Integer.parseInt
para fazer o trabalho, e minha soluçãoInts.tryParse()
),int[]
,Box
,OptionalInt
),CharSequence
parte ou parte dele em vez de um todoString
,Integer.parseInt
possa, ou seja, [2,36],A única desvantagem é que não há diferença entre
toIntOfDefault("-1", -1)
etoIntOrDefault("oops", -1)
.fonte
Você pode usar um objeto nulo da seguinte forma:
O resultado de main neste exemplo é:
Dessa forma, você sempre pode testar a falha na conversão, mas ainda assim trabalhar com os resultados como instâncias inteiras. Você também pode querer ajustar o número que NULL representa (≠ 0).
fonte
Você não deve usar exceções para validar seus valores .
Para um único caractere, há uma solução simples:
Para valores mais longos, é melhor usar alguns utilitários. NumberUtils fornecidos pelo Apache funcionariam perfeitamente aqui:
Verifique https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html
fonte
Integer.parseInt
.