Como faço para impedir que um scanner jogue exceções quando o tipo errado é inserido?
-
21-09-2019 - |
Pergunta
Aqui está algum código de amostra:
import java.util.Scanner;
class In
{
public static void main (String[]arg)
{
Scanner in = new Scanner (System.in) ;
System.out.println ("how many are invading?") ;
int a = in.nextInt() ;
System.out.println (a) ;
}
}
Se eu executar o programa e dar um int
Curti 4
, então tudo vai bem.
Por outro lado, se eu responder too many
Não ri da minha piada engraçada. Em vez disso, entendo isso (como esperado):
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at In.main(In.java:9)
Existe uma maneira de fazê -lo ignorar entradas que não são ints ou são prontas para "Quantos estão invadindo?" Eu gostaria de saber como fazer os dois.
Solução
Você pode usar um dos muitos hasNext*
Métodos isso Scanner
tem para pré-validação.
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
Isso impede InputMismatchException
até ser jogado, porque você sempre se certifica de que isso VAI Combine antes de lê -lo.
java.util.Scanner API
boolean hasNextInt()
: Retornatrue
Se o próximo token na entrada deste scanner puder ser interpretado como um valor int no radix padrão usando onextInt()
método. O scanner não avança em nenhuma entrada.String nextLine()
: Avança esse scanner além da linha atual e retorna a entrada que foi ignorada.
Lembre -se das seções em negrito. hasNextInt()
não adianta além de nenhuma entrada. Se retornar true
, você pode avançar o scanner ligando nextInt()
, que não jogará um InputMismatchException
.
Se retornar false
, então você precisa pular o "lixo". A maneira mais fácil de fazer isso é apenas ligando nextLine()
, provavelmente duas vezes, mas pelo menos uma vez.
Por que você pode precisar fazer nextLine()
duas vezes é o seguinte: Suponha que esta seja a entrada inserida:
42[enter]
too many![enter]
0[enter]
Digamos que o scanner esteja no início dessa entrada.
hasNextInt()
é verdade,nextInt()
retorna42
; Scanner está agora em pouco antes o primeiro[enter]
.hasNextInt()
é falso,nextLine()
Retorna uma corda vazia, um segundonextLine()
retorna"too many!"
; Scanner está agora em logo após o segundo[enter]
.hasNextInt()
é verdade,nextInt()
retorna0
; Scanner está agora em pouco antes o terceiro[enter]
.
Aqui está um exemplo de juntar algumas dessas coisas. Você pode experimentar para estudar como Scanner
funciona.
Scanner in = new Scanner (System.in) ;
System.out.println("Age?");
while (!in.hasNextInt()) {
in.next(); // What happens if you use nextLine() instead?
}
int age = in.nextInt();
in.nextLine(); // What happens if you remove this statement?
System.out.println("Name?");
String name = in.nextLine();
System.out.format("[%s] is %d years old", name, age);
Digamos que a entrada seja:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Então a última linha da saída é:
[Elvis, of course] is 100 years old
Outras dicas
Em geral, eu realmente não gosto de usar a mesma biblioteca para a leitura e a análise. As bibliotecas de idiomas parecem ser muito inflexíveis e muitas vezes não podem ser dobradas à sua vontade.
A primeira etapa que retira dados do System.in NÃO deve ser capaz de falhar, então o leia como uma string em uma variável e converta essa variável de sequência em um int. Se a conversão falhar, ótimo-imprima seu erro e continue.
Quando você envolve seu fluxo com algo que pode dar uma exceção, fica meio confuso exatamente em que afirma toda a bagunça deixa seu fluxo.
É sempre um benefício para tenho seu aplicativo lançar um erro quando ocorre um erro em oposição a maneiras de guarda Isso aconteceu.
Uma alternativa é envolver o código dentro de um try {...}
catch {...}
bloco para InputMismatchException
. Você também pode querer envolver o código dentro de um while
loop para ter o Scanner
Continue solicitando até que uma condição específica seja atendida.