Java扫描器不等待输入
我在这里有两个代码块.一台扫描仪正确等待用户输入,另一台扫描仪直接通过它并调用nextInt()
并返回NoSuchElementException
.这是有效的块:
I have two blocks of code here. One scanner properly waits user input, and the other just blows right through it and calls nextInt()
which returns a NoSuchElementException
. Here is the block that works:
public void startGame() {
out.println("Player1: 1 for dumb player, 2 for smart player, 3 for human player.");
Scanner scan = new Scanner(System.in);
p = scan.nextInt();
if (p == 1)
p1 = new DumbPlayer("ONE");
if (p == 2)
p1 = new SmartPlayer("ONE");
else
p1 = new HumanPlayer("ONE");
out.println("Player2: 1 for dumb player, 2 for smart player, 3 for human player.");
p = scan.nextInt();
if (p == 1)
p2 = new DumbPlayer("TWO");
if (p == 2)
p2 = new SmartPlayer("TWO");
else
p2 = new HumanPlayer("TWO");
scan.close();
这是没有的块:
public int findBestMove(Set<Integer> moves, Board b) {
Set<Integer> set = new HashSet<Integer>();
out.println("Player " +name+ ", select a column from 1-7: ");
Scanner scan = new Scanner(System.in); <--here it should wait for input, but does not!
int move = scan.nextInt(); <-- NoSuchElementException
scan.close();
for (int x = 1; x <= 7; x++) {
set.add(move);
move += 7;
}
....etc
这两个都是单独的类,并且是从另一个类的main方法中调用的.基本上main()
会调用startGame()
,这又会调用某些Player类的findBestMove()
方法...这是无效代码所在的位置.程序中是否有不适合进行输入的时间?我的印象是,只要需要用户输入,就可以使用这种方法.谢谢!
Both of these are separate classes, and are called from a main method in yet another class. Basically main()
calls startGame()
, which in turn calls the findBestMove()
method of some Player class...which is where the non-working code resides. Are there times in the program where it is not appropriate to take input? I was under the impression that anytime I wanted user input, I could use this approach. Thanks!
根据 InputStream ,它实现了Closeable
界面.因此,在与System.in
关联的Scanner
上调用Scanner.close()
之后,System.in
流将关闭并且不再可用.
According to the java.util.Scanner javadoc, Scanner.close()
closes the associated stream if this stream implements the Closeable
interface. java.lang.System.in
is an InputStream, which implements the Closeable
interface. Hence, after calling Scanner.close()
on a Scanner
which is associated with System.in
, the System.in
stream is closed and not available anymore.
以下SSCCE对我有用.我从问题中删除了一些与实际问题无关的代码.请注意,使用这种方法时,Eclipse会向我发出警告"Resource leak: 'scan' is never closed"
,因此更好的解决方案是仅使用一个Scanner实例.
The following SSCCE works for me. I have removed some code from the question which is not relevant to the actual issue. Note that with this approach, while it works, Eclipse gives me the warning "Resource leak: 'scan' is never closed"
, so a better solution would be to use one Scanner instance only.
package com.example;
import java.util.Scanner;
import java.util.Set;
import static java.lang.System.out;
public class ScannerTest {
int p = 0;
String name = "Test";
public void startGame() {
out.println("Player1: 1 for dumb player, 2 for smart player, 3 for human player.");
Scanner scan = new Scanner(System.in);
p = scan.nextInt();
out.println("Result1: " + p);
out.println("Player2: 1 for dumb player, 2 for smart player, 3 for human player.");
p = scan.nextInt();
out.println("Result2: " + p);
// scan.close(); // Do not close the Scanner to leave System.in open
}
public int findBestMove(Set<Integer> moves, Object /*Board*/ b) {
out.println("Player " +name+ ", select a column from 1-7: ");
Scanner scan = new Scanner(System.in);
int move = scan.nextInt();
// scan.close(); // Do not close the Scanner to leave System.in open
out.println("Move: " + move);
return 0;
}
public void run() {
startGame();
findBestMove(null, null);
}
public static void main(String[] args) {
ScannerTest st = new ScannerTest();
st.run();
}
}