如何防止扫描仪在input错误types时抛出exception?

以下是一些示例代码:

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) ; } } 

如果我运行程序,并给它一个像4这样的int ,那么一切都很好。

另一方面,如果我回答too many ,不会笑我的笑话。 相反,我得到这个(如预期):

 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) 

有没有办法让它忽略那些没有ints的条目,或者用“有多less入侵? 我想知道如何做到这一点。

您可以使用Scanner用于预validation的众多hasNext*方法之一。

  if (in.hasNextInt()) { int a = in.nextInt() ; System.out.println(a); } else { System.out.println("Sorry, couldn't understand you!"); } 

这可以防止InputMismatchException被抛出,因为在读取之前,您总是确保它会匹配。


java.util.Scanner API

  • boolean hasNextInt() :如果此扫描器input中的下一个标记可以使用nextInt()方法解释为默认基数中的整型值,则返回true扫描仪不会超过任何input。

  • String nextLine() :使此扫描器前进到当前行,并返回被跳过的input。

请记住粗体部分。 hasNextInt()不会超越任何input。 如果返回true ,则可以通过调用nextInt()来推进扫描器,而不会抛出InputMismatchException

如果它返回false ,那么你需要跳过“垃圾”。 最简单的方法是调用nextLine() ,可能两次,但至less一次。

为什么你可能需要做nextLine()两次,如下所示:假设这是input的input:

 42[enter] too many![enter] 0[enter] 

假设扫描仪在input的开始处。

  • hasNextInt()为true, nextInt()返回42 ; 扫描仪现在就在第一个[enter]
  • hasNextInt()为false, nextLine()返回空string, nextLine()返回"too many!" ; 扫描仪现在在第二个[enter]
  • hasNextInt()为true, nextInt()返回0 ; 扫描仪现在就在第三个[enter]

这是把这些东西放在一起的一个例子。 您可以尝试使用它来研究Scanner如何工作。

  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); 

假设input是:

 He is probably close to 100 now...[enter] Elvis, of course[enter] 

然后输出的最后一行是:

 [Elvis, of course] is 100 years old 

一般来说,我真的很不喜欢使用相同的库调用来读取和parsing。 语言图书馆似乎非常不灵活,往往不能屈服于你的意愿。

从System.in中提取数据的第一步不应该是失败的,所以它将它作为一个string读入一个variables,然后将该stringvariables转换为一个int。 如果转换失败,很好 – 打印错误并继续。

当你用一些可以抛出exception的东西包装你的stream时,它会让整个混乱离开你的stream的状态变得混乱。

当发生错误的时候,让应用程序抛出一个错误,反对防止错误的发生,这总是一个好处。

一种替代方法是将代码包装在InputMismatchExceptiontry {...} catch {...}块中。 您可能还想要将代码封装在一个while循环中,让Scanner保持提示状态,直到满足特定的条件。