这是来自Java的Scanner next()方法说明:
此方法可能在等待输入扫描时阻塞,即使a 之前的hasNext()调用返回true。
如果调用hasNext(),该方法如何等待输入用户输入?如果我们调用hasNext()并返回true,我们知道有下一个标记,那么next()方法如何以及为什么这样做?
答案 0 :(得分:2)
您需要阅读方法的完整 documentation:
从此扫描仪查找并返回下一个完整令牌。一个 完整标记之前和之后是匹配的输入 分隔符模式。此方法可能在等待输入时阻塞 扫描,即使之前的hasNext()调用返回true。
当有另一个令牌时,Scanner#hasNext
方法(documentation)可能会返回true
。但根据分隔符模式,令牌可能仍未被视为完整,并且Scanner#next
将始终阻止,直到令牌完成。< / p>
如果Scanner
中有完整令牌,则Scanner#next
会立即返回,不会阻止。
您可以使用Scanner#useDelimiter
方法(documentation)设置分隔符模式
如果您未设置特定的分隔符模式,则Scanner
将使用与空白字符匹配的默认模式。
正如您所问,已阻止表示该方法等待,直到所述事件发生后才会返回。
考虑一下:
System.out.println("Before");
someBlockingMethod();
System.out.println("After");
使用
public void someBlockingMethod() {
// Sleep for a second (ignoring exceptions for simplicity)
Thread.sleep(1000);
}
只有After
返回后才会看到someBlockingMethod()
,这只会在上述事件发生后才会发生。因此,方法阻止。在该示例中,该方法阻止一秒钟。
答案 1 :(得分:1)
Scanner#next
在到达Scanner
使用的分隔符(空格是默认分隔符)之前或者到达输入流的末尾之前不返回字符串。 / p>
如果hasNext
返回true,则表示输入流中肯定有更多数据,但它可能仍需要阻塞,直到达到分隔符/ EOF。
答案 2 :(得分:1)
如果您调试以下代码,您会看到实际上是阻塞并等待用户输入的hasNext()方法:
Scanner scanner = new Scanner(System.in);
if (scanner.hasNext()) {
String s = scanner.next();
}
那是因为hasNext()中有一个阻塞步骤:
public boolean hasNext() {
ensureOpen();
saveState();
while (!sourceClosed) {
if (hasTokenInBuffer())
return revertState(true);
readInput(); //THIS IS WAITING FOR USER INPUT
}
...
在控制台输入的情况下,hasNext()等待直到输入完整的令牌并返回true,然后后续的next()调用不会阻塞。
在非控制台输入的情况下,即使没有完整的令牌,hasNext()也会返回true,后续的next()调用会阻塞并等待完整的令牌。