我正在尝试编写一种方法,使人们可以通过扫描程序输入整数,而不会因程序异常而导致程序崩溃。这是我最初的所作所为:(此处,sc是扫描仪对象)
public static int inputInt(String message) {
int returnval = 0;
System.out.println(message);
try {
returnval = sc.nextInt();
} catch (Exception ex) {
System.out.println("You must enter an integer.");
inputInt(message);
}
return returnval;
}
当我使用无效输入测试程序时,启动了无限循环,消息和"您必须输入一个整数"在被Eclipse停止之前被多次打印。 我使用以下代码修复了这个问题:
public static int inputInt(String message) {
int returnval = 0;
System.out.println(message);
String valstring = sc.nextLine();
try {
returnval = Integer.parseInt(valstring);
} catch (Exception ex) {
System.out.println("You must enter an integer.");
inputInt(message);
}
return returnval;
}
为什么第一种方法失败,而第二种方法失败?可能有更清洁的方法来实现这个目标吗?
答案 0 :(得分:2)
是的,方法更简洁:使用hasNextInt
:
public static int inputInt(String message) {
System.out.println(message);
while (!sc.hasNextInt()) {
sc.nextLine(); // clear the bad input first
System.out.println("You must enter an integer.");
System.out.println(message); // why use recursion? just use a while loop
}
return sc.nextInt();
}
我所做的改变:
hasNextInt
,因此您不必使用例外sc.nextLine();
(问题的根源)答案 1 :(得分:1)
Scanner.nextInt()
有能力抛出3个例外:
1- InputMismatchException
:当下一个项目不是int
时抛出。
2- NoSuchElementException
:当没有下一个东西时。
3- IllegalStateException
:如果Scanner
已关闭。
因此,当您输入非法值(例如“abc”)时,顶部代码会执行此操作:
取“abc”并尝试将其转换为int。 (nextInt()
)。因为“abc”不是数字,所以它无法转换,并抛出InputMismatchException
。但是,由于方法没有成功完成,“abc”将作为下一个要读取的项目。因为抛出了异常,所以运行catch
块中的代码。它打印出“你必须输入一个整数”。然后它再次调用自己,传递自己message
。然后它会初始化returnval
并从第一次运行中打印出相同的message
,因为您再次将它传递给自己。然后输入try
块,因为“abc”未成功读取并留在那里,扫描仪会读取“abc”并尝试再次将其转换为int
。当然,这不起作用,循环再次开始。
现在您知道您的问题是什么,您可以找到解决方案。我认为最优雅的方法是使用Scanner
方法hasNextInt()
。这将返回boolean
,告知您是否可以将要阅读的下一个项目转换为int
。例如,如果下一个项目是“abc”,则该方法将返回false
。对于下一个项目“1”,该方法将返回true
。因此,如果您像这样修改代码,它应该可以工作:
public static int inputInt(String message) {
int returnval = 0;
System.out.println(message);
while(!sc.hasNextInt()) {
sc.nextLine();
System.out.println("You must enter an integer.");
}
returnval = sc.nextInt();
return returnval;
}
此代码的作用:
1-初始化returnval
并打印出message
。
2-只要扫描仪没有int
可读,就进入while循环。有效地“等待”下一个int
输入。
3-一旦有int
读取,它将读取int并将值保存在returnval
中。
4-它将returnval
返回给调用者。
(缓慢而稳定地赢得比赛,哈哈。我似乎总是很慢的回答。也许是因为我写小小说作为答案....;)