【发布时间】:2018-11-30 16:23:06
【问题描述】:
不进则出扫描器的价值——Java
我想在扫描仪中获取输入的值而不推进它。目前,我使用我的扫描仪输入为System.in。
final var sc = new Scanner(System.in);
我知道扫描仪上的 hasNext 方法,它们是目前我最好/唯一的方法来检查其输入而不推进它。
例如,我如何确保来自sc 的正整数输入。
public static int getPositiveIntegerInput(Scanner sc) {
System.out.println("Please input a positive integer");
sc.useDelimiter("\n");
while (!sc.hasNextInt() || sc.hasNext(".*[^\\d].*")) {
System.out.println("Invalid input, please try again");
sc.nextLine();
}
return sc.nextInt();
}
我想将这种检查sc 的输入而不推进它的概念扩展为实际获取sc 的输入而不推进它。
到目前为止我所做的尝试
我已经在Scanner上浏览了hasNext()的实现细节。
hasNext的实现:
public final class Scanner {
public boolean hasNext(Pattern pattern) {
ensureOpen();
if (pattern == null)
throw new NullPointerException();
hasNextPattern = null;
saveState();
modCount++;
while (true) {
if (getCompleteTokenInBuffer(pattern) != null) {
matchValid = true;
cacheResult();
return revertState(true);
}
if (needInput)
readInput();
else
return revertState(false);
}
}
}
至少在我看来,可以通过getCompleteTokenInBuffer 方法获得扫描仪的输入,但我真的不明白它是如何工作的。我不知道该方法是否单独获得扫描仪的值而不推进它,或者如果它推进它然后其他东西将它恢复到它在输入之前的状态,就好像它根本没有推进一样,或者如果它将它与其他东西结合起来,或者根本没有。
我一直在尝试通过 Java 的反射 API 调用私有方法 Scanner,以尝试在没有实际推进方法的情况下实际返回持有 sc 输入值的令牌(但老实说,我只是玩弄它,不知道如何真正完成我想做的事情)。
public static void main(String[] args) {
final var sc = new Scanner(System.in);
sc.useDelimiter("\n");
var str = "";
try {
Method method = Scanner.class.getDeclaredMethod("getCompleteTokenInBuffer", Pattern.class);
method.setAccessible(true);
str = (String) method.invoke(sc, Pattern.compile(".*"));
} catch (Exception e) {
System.out.println("Well, that didn't work!");
System.out.println("Exception: " + e);
}
System.out.println("getCompleteTokenInBuffer: " + str);
// Prints: "getCompleteTokenInBuffer: null"
}
注意:上述方法在获取sc的输入值之前不会等待输入,因此返回值null。
目标:
重申一下,我想设法捕获并返回 Scanner 对象的输入值并实际推进它。
【问题讨论】:
标签: java input reflection token java.util.scanner