我从另一个程序中复制了完全相同的代码。每当输入故意的错误结果时,仍会发生InputMismatchException并且程序崩溃。
import java.util.*;
public class Runner{
public static void main (String args[]){
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\n");
Fixture f = new Fixture();
boolean inputValid = false;
int choice = 0;
do{
do {
System.out.println("\f\t\tFootball Database");
System.out.println("A utility to help make footballing events easier to manage.");
System.out.println("");
System.out.println("\t> Press 1 to manage players ");
System.out.println("\t> Press 2 to manage teams");
System.out.println("\t> Press 3 to manage coaches");
System.out.println("\t> Press 4 to manage fixtures");
System.out.println("\t> Press 5 to save database to file");
System.out.println("\t> Press 6 to load database from file");
System.out.println("\t> Press 7 to terminate program");
System.out.println("");
System.out.println("");
System.out.println("©Thomas Camilleri 2017");
try{
choice = sc.nextInt();
inputValid = true;
}catch(InputMismatchException e){
System.out.println("Invalid input");
inputValid = false;
sc.nextInt();
sc.nextInt();
}
}while(inputValid == false);
答案 0 :(得分:1)
以下是您的代码的重要部分:
try {
choice = sc.nextInt(); // NOT HERE
inputValid = true;
} catch(InputMismatchException e){
System.out.println("Invalid input");
inputValid = false;
sc.nextInt(); // HERE
sc.nextInt();
}
如果您查看自己的堆栈跟踪,并查看行号,您会看到代码中发生异常的行是我用// HERE
标记的行。
(编译并运行原始程序并查看堆栈跟踪以了解我的意思。将堆栈跟踪中的行号与源代码进行比较。)
如您所见,该行不在try { ... }
块中。它位于异常处理程序块中。
发生的事情是您捕获了标记为// NOT HERE
的行所引发的异常,然后再次调用sc.nextInt()
(// HERE
)。第二个调用只是尝试再次读取相同的输入字符。
nextInt
方法的行为如下:
我强烈建议您仔细阅读Scanner
课程的javadocs,以便了解您实际使用的方法。
所以...正如你所看到的...如果你在nextInt()
电话失败后拨打nextInt()
,你就会重复同样的失败。
没有捕到第二个异常的原因是它没有被抛出try { ... }
块。
解决方案:您应该调用一个只会丢弃垃圾的方法,而不是在处理程序中调用nextInt()
。在这种情况下,最明智的做法是扔掉一切直到下一行的结尾。
提示#1:nextLine()
将所有内容都提升到下一个行尾。阅读该方法的javadocs。
提示#2:如果你理解我所说的话,你就会知道在哪里修改。
答案 1 :(得分:-1)
尝试:
choice = Integer.parseInt(sc.nextLine());
你的程序会喜欢这个:
try (Scanner sc = new Scanner(System.in)) {
sc.useDelimiter("\n");
// Fixture f = new Fixture();
boolean inputValid = false;
int choice = 0;
// removed outer do..while(); loop
do {
System.out.println("\f\t\tFootball Database");
System.out.println("A utility to help make footballing events easier to manage.");
System.out.println("");
System.out.println("\t> Press 1 to manage players ");
System.out.println("\t> Press 2 to manage teams");
System.out.println("\t> Press 3 to manage coaches");
System.out.println("\t> Press 4 to manage fixtures");
System.out.println("\t> Press 5 to save database to file");
System.out.println("\t> Press 6 to load database from file");
System.out.println("\t> Press 7 to terminate program");
System.out.println("");
System.out.print("Enter your choice : ");
try{
// Always use nextLine() if you mix String and basic Datatype
choice = Integer.parseInt(sc.nextLine());
inputValid = true;
}catch(NumberFormatException e){
System.out.println("Invalid input");
inputValid = false;
// Removed unnecessary two sc.nextInput() lines
}
}while(inputValid == false);
System.out.println("choice is : " + choice);
}