Java中误关闭Scanner后抛出IllegalStateException如何重置?
核心结论
没有办法通过重置Scanner本身来恢复输入能力,报错的根源是Scanner绑定的底层Readable输入流已经被关闭,流的关闭状态是不可恢复的,必须从输入流的层面处理。
问题根源
Scanner.close()方法被调用时,会同步关闭其绑定的底层Readable输入源。你之前调试时运行过带close()的代码,已经把成员变量this.reader对应的流关闭了,即便你后续删除了close()调用,已经关闭的流状态也不会自动重置,所以新建Scanner绑定同一个已经关闭的this.reader时,就会抛出IllegalStateException。
解决方法
根据你this.reader的类型不同,对应处理方案如下:
- 如果
this.reader是绑定System.in的流:- 彻底删除所有代码中对绑定
this.reader的Scanner的close()调用,也不要直接调用this.reader.close()。System.in是JVM全局的输入流,程序运行期间不需要手动关闭,JVM退出时会自动回收。 - 重启当前运行的应用程序,重启后
System.in会重新初始化,之前的关闭状态就会清空。
- 彻底删除所有代码中对绑定
- 如果
this.reader是自定义可重开的流(比如文件流、字符串流):
每次调用playGame方法前重新初始化this.reader,生成新的未关闭的流实例即可,不需要复用之前被关闭的流对象。
代码调整参考
你当前的代码逻辑本身没有问题,只需要注意不要加关闭操作,同时修正原代码里的变量拼写错误即可:
public void playGame() { String nextInput; Scanner scanner = new Scanner(this.reader); promptMove(); while (!(this.model.isGameOver())) { if (scanner.hasNext()) { nextInput = scanner.next(); if (nextInput.equalsIgnoreCase("q")) { promptQuit(); break; } else { addInputs(nextInput); } // 原代码此处input变量未定义,修正为nextInput attemptControllerMove(nextInput); } else { throw new IllegalStateException("Please enter valid moves."); } } if (this.model.isGameOver()) { promptGameOver(); } // 禁止添加 scanner.close() 或者 this.reader.close() 代码 }
内容的提问来源于stack exchange,提问作者Gianna M
相关产品推荐
相关产品推荐

