Java 在方法内重新打开扫描仪时出现NoTouchElementException
下面是引发异常的代码的简化版本Java 在方法内重新打开扫描仪时出现NoTouchElementException,java,java.util.scanner,nosuchelementexception,system.in,Java,Java.util.scanner,Nosuchelementexception,System.in,下面是引发异常的代码的简化版本 static String s1; static String s2; static void getString(String s) { Scanner sc = new Scanner(System.in); s = sc.nextLine(); sc.close(); } public static void main(String[] args) { getString(s1); getString(s2); }
static String s1;
static String s2;
static void getString(String s) {
Scanner sc = new Scanner(System.in);
s = sc.nextLine();
sc.close();
}
public static void main(String[] args) {
getString(s1);
getString(s2);
}
线程“main”java.util.NoSuchElementException中的异常:无行
可在以下位置找到java.util.Scanner.nextLine(Scanner.java:1540)
temp.temp.getString(temp.java:13)
我调用了两次getString
方法,第二次调用时,它会断开:
s = sc.nextLine();
现在,我知道删除sc.close()
行可以解决这个问题(并且使sc
成为一个静态变量也很可能)。我需要理解的是为什么会这样
我阅读了扫描器
类的规范,但无法推断。我还读了几篇关于这个异常的文章,其中一篇说关闭扫描器也会关闭底层流。但是我正在创建一个新的扫描器,并用每个方法调用重新打开流,不是吗?没有“重新打开流”这样的事情。您唯一能做的就是使用新的扫描仪创建一个新的流,并可以选择将其放置在同一个变量中
一旦您关闭sc
,您也将关闭流中的底层系统。在它上面创建一个新的扫描器
无法“重新打开”它,并且由于流已关闭,因此会出现此异常
长话短说——虽然在使用完资源后关闭它们绝对是一种好的做法,但不应该关闭System.in
(或基于它的任何扫描仪)。如前所述,您不能“重新打开”System.in、System.out或System.err
作为解决此问题的另一个解决方案,您可以使用CloseShieldInputStream,正如所述,您并不是在创建新的流。您总是使用相同的流:System.in。当它关闭时,它就关闭了。@JBNizet,是的,注意到了,只是将此更正为“重新打开”。不过,这个问题仍然存在。或者你的意思是,一旦关闭,它无论如何都不能重新打开?当你关闭扫描仪时,它会关闭它正在使用的流,即System.inNo,你不会“重新打开”任何东西。流无法重新打开,并且任何地方都没有“重新打开”。您使用的是单个流,当它关闭时,它就关闭了。永远