假设我有String s
,我想在Builder中使用Scanner通过此方法迭代它:
private void scan(String s){
Scanner scanner = new Scanner(s);
while (scanner.hasNext()){
//do something
}
}
我们假设s
是一个变量,是另一个Object
的一部分。
public class Person{
String name;
//rest of code
}
现在让我们假设这个对象存储在一个Singleton中,该Singleton存储数据以便在程序的生命周期内随时可用
public class Singleton{
private List<Person> list = new ArrayList<>();
//rest of code
}
我的问题是:scanner
完成运行后scan(String s)
会发生什么?它会保持活力还是会在达到其范围后收集,从而释放资源?如果没有收集,如果我将scan(String s)
更改为:
private void scan(String s){
Scanner scanner = new Scanner(s);
while (scanner.hasNext()){
//do something
}
scanner.close();
}
或者后一种形式是否应该首选?
答案 0 :(得分:1)
对于Scanner
上的String
,扫描程序将有StringReader
作为其源,它将引用字符串,但不会引用扫描程序本身。由于StringReader纯粹是在内存中,因此不需要关闭或清理。但是,关闭它没有任何害处,但是如果你确实选择关闭它,你应该将调用关闭在finally
块中,或者通过使用try-with-resources使其隐式:
Scanner scanner = new Scanner(s);
try {
while (scanner.hasNext()) {
// do something
}
} finally {
scanner.close();
}
或者:
try (Scanner scanner = new Scanner(s)) {
while (scanner.hasNext()) {
// do something
}
} // close will be implicitly called
规则是,您应该始终关闭您打开的任何内容,以确保清理资源。
对于文件上的扫描仪,关闭它非常重要。
对于System.in
上的扫描程序,您没有打开 System.in,因此关闭它不是您的责任。
对于字符串上的扫描程序,或者从ByteArrayInputStream
或StringReader
进行阅读时,没有任何有意义的资源可以关闭,但它可能是最好的以一种关闭将被调用的方式写东西,以防你以后再切换它来读取文件(或者只是为了养成习惯)。
关于垃圾收集的问题,你永远不能真正说出什么时候会收集垃圾。如果您的程序永远不会运行内存不足,垃圾收集器甚至可能无法运行。但是既然String和StringReader都没有维护对Scanner的引用,只要方法scan(String)
中的局部变量对它的引用消失,它就会符合条件进行垃圾回收。回报。
答案 1 :(得分:0)
始终首选关闭文件上的扫描程序,以便可以确定地清理文件资源。
可以在丢弃扫描仪后清除字符串,假设它没有在其他任何地方引用。
对于扫描仪,我建议使用try-with-resource
try (Scanner scanner = new Scanner(filename)) {
while (scanner.hasNext()){
//do something
}
}