您的位置:首页 > 其它

Scanner类throwFor(Unknown Source)及跳过下一个扫描器分析

2015-08-01 15:08 302 查看
在使用Scanner类时遇到一个问题:

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)


在执行scanner.next()时遇到异常。Stack Overflow上给出了问题原因与解决办法。

原因:当一个类中两个及两个以上的Scanner实例时,其中一个Scanner类的实例执行scanner.close()方法会关闭其他潜在的InputStream流,导致其他Scanner的扫描器无法读取输入流。

解决办法:对于控制台程序,在程序运行中只注册一个Scanner类的实例从System.in中读取信息。

问题二:使用Scanner#nextInt()时跳过下一个扫描器。

产生原因:在使用Scanner#nextInt()时,nextInt()在遇到 '\n'之前结束,但“\n"会被下一个扫描器所接收,如Scanner#nextLine(),从而直接跳过Scanner#nextLine()。

解决办法:统一使用Scanner#nextLine()代替所有扫描函数。然后进行强制类型转换。

String nextIntString = keyboard.nextLine(); //get the number as a single line
int nextInt = Integer.parseInt(nextIntString); //convert the string to an int


补充:在使用Scanner#hasNextInt(),hasNextDouble()...函数时,如果返回值为false则应该在else语句中增加Scanner#nextLine()以抵消 '\n'。

public void showMenu() {
System.out.println("****************************");
System.out.println("Option Menu");
System.out.println("1、登录");
System.out.println("2、注册");
System.out.println("3、退出");
System.out.println("请选择:");
System.out.println("****************************");
if (scanner.hasNextInt()) {
int index = Integer.parseInt(scanner.nextLine());
choice(index);
} else {
scanner.nextLine();
System.out.println("请输入数字...");
showMenu();
}
}


问题一解释

You close the second
Scanner
which closes the underlying
InputStream
, therefore the first
Scanner
can no longer read from the same
InputStream
and a
NoSuchElementException
results.

The solution: For console apps, use a single
Scanner
to read from
System.in
.

Aside: As stated already, be aware that
Scanner#nextInt
does not consume newline characters. Ensure that these are consumed before attempting to call
nextLine
again by using
Scanner#newLine()
.

问题二解释:

The
nextInt()
method leaves the
\n
(end line) symbol and is picked up immediately by
nextLine()
, skipping over the next input. What you want to do is use
nextLine()
for everything, and parse it later:

String nextIntString = keyboard.nextLine(); //get the number as a single line
int nextInt = Integer.parseInt(nextIntString); //convert the string to an int

This is by far the easiest way to avoid problems--don't mix your "next" methods. Use only
nextLine()
and then parse
int
s or separate words afterwards.

Also, make sure you use only one
Scanner
if your are only using one terminal for input. That could be another reason for the exception.

Last note: compare a
String
with the
.equals()
function, not the
==
operator.

if (playAgain == "yes"); // Causes problems
if (playAgain.equals("yes")); // Works every time
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: