Java 未关闭扫描仪的垃圾收集
为了绕过这个问题,并使代码更干净,我曾多次使用以下方法:Java 未关闭扫描仪的垃圾收集,java,garbage-collection,java.util.scanner,Java,Garbage Collection,Java.util.scanner,为了绕过这个问题,并使代码更干净,我曾多次使用以下方法: private String getInput() { return new Scanner(System.in).nextLine(); } 这不是任何生产代码,只是小项目,所以我不太关心这是否会带来性能问题,因为我发现这种方法非常方便。我非常喜欢对所有输入使用这个方法,并解析返回值 问题是,这是一种非常糟糕的做法吗?不关闭扫描仪我感觉不太好,但由于对象无法触及,我一直认为扫描仪对象应该被垃圾收集,因此也应该关闭。gc如何处理
private String getInput() {
return new Scanner(System.in).nextLine();
}
这不是任何生产代码,只是小项目,所以我不太关心这是否会带来性能问题,因为我发现这种方法非常方便。我非常喜欢对所有输入使用这个方法,并解析返回值
问题是,这是一种非常糟糕的做法吗?不关闭扫描仪我感觉不太好,但由于对象无法触及,我一直认为扫描仪对象应该被垃圾收集,因此也应该关闭。gc如何处理这个问题?扫描器有一个
finalize()
方法,当对象是gc时,该方法将关闭任何本机资源。扫描器有一个finalize()
方法,当对象为GC'd时,该方法将关闭任何本机资源。在这种情况下,您不能关闭它,否则系统。in
也将关闭,这样您将无法获得任何新输入,如果您执行以下简单代码:
Scanner scanner = new Scanner(System.in);
scanner.close();
scanner = new Scanner(System.in);
scanner.nextLine(); // -> Exception here
您将获得下一个异常:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at hello.Application.main(Application.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
我看到您的方法的唯一真正问题是,如果您在每次调用时创建一个新的Scanner
实例时定期调用此方法,则效率可能会很低,此外,它可能是JDK实现特有的,因为如果您有一个实现方法finalize
的Scanner
实现,它可能会关闭Scanner
,这将导致上述错误。在这种情况下,您不能关闭它,否则系统将关闭如果执行以下简单代码,您将无法获得任何新输入:
Scanner scanner = new Scanner(System.in);
scanner.close();
scanner = new Scanner(System.in);
scanner.nextLine(); // -> Exception here
您将获得下一个异常:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at hello.Application.main(Application.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
我看到您的方法的唯一真正问题是,如果您在每次调用时创建一个新的Scanner
实例时定期调用此方法,则效率可能会很低,此外,它可能是特定于JDK实现的,因为如果您有一个实现方法finalize
的Scanner
实现,它可能会关闭Scanner
,这将导致上述错误。但是这种方法是一种不好的做法吗?如果是,为什么?我认为这是一种糟糕的做法,想象一下为每个输入创建新对象,而不是只创建一个!!我建议你编辑你的答案我在scanner中看不到任何finalize方法你使用哪种JDK?嗯,是的,在FileInputStream
级别有一个finalize()
。但是这种方法是不是不好的做法?如果是,为什么?我认为这是一种糟糕的做法,想象一下为每个输入创建新对象,而不是只创建一个!!我建议您编辑您的答案我在扫描仪中没有看到任何finalize方法您使用哪种JDK?嗯,是的,在FileInputStream
级别有一个finalize()
。您能更彻底地解释上面的错误吗,我不明白这个问题吗?当然,我理解它的效率很低,但是性能影响必须是最小的。检查扫描仪的关闭方法,如果关闭扫描仪,它也会关闭源,这是系统。在这里,你不能再读取输入流如果你做了几次,确实影响应该是最小的,这取决于你的用例很好,我现在看到了,很好的解释,也测试了你的例子,它给了我那个错误。无论如何,我不能用我的方法产生这个错误。现在我很好奇为什么这个getInput()方法不会导致任何错误。仅仅因为扫描器从未关闭,它只是垃圾收集。你能更彻底地解释上面的错误吗,我不明白这个问题吗?当然,我理解它的效率很低,但是性能影响必须是最小的。检查扫描仪的关闭方法,如果关闭扫描仪,它也会关闭源,这是系统。在这里,你不能再读取输入流如果你做了几次,确实影响应该是最小的,这取决于你的用例很好,我现在看到了,很好的解释,也测试了你的例子,它给了我那个错误。无论如何,我不能用我的方法产生这个错误。现在我很好奇为什么这个getInput()方法不会导致任何错误。因为扫描器从未关闭,所以它只是垃圾收集