如果我有一个抛出FilenotFoundException的方法,因为我正在使用Scanner对象来读取文件,如果实际上抛出了错误,是否会关闭scanner对象,或者在处理异常时仍然需要这样做?
我知道当我在我的方法中使用try-catch-finally块写入来处理异常时,我关闭了扫描器对象,但如果我必须在另一个捕获异常的对象的方法中执行它,我将无法访问扫描仪对象。
请保持解释简单......显然我是java的新手(和OO一般)。
答案 0 :(得分:3)
如果您使用的是这样的代码
Scanner scanner = new Scanner(new File("C:/abc.txt"));
如果它抛出异常,则不会创建scanner
对象,因此不需要关闭它。
但最好的编码方式如下。你可以在最后阻止。
Scanner scanner=null;
try
{
scanner = new Scanner(new File(path));
//your code here
}
catch(FileNotFoundException e)//either catch or throw out
{
//log it
}
finally
{
if(null !=scanner)
{
scanner.close();
}
}
答案 1 :(得分:2)
如果在执行FileInputStream
时找不到该文件,则甚至不会打开基础new Scanner(File)
。
最好在 finally 块中关闭扫描仪。如果扫描仪已关闭,则关闭呼叫将无效。
或者您可以尝试try-with-resources
构造,如果发生某些异常,它将自动关闭资源。
答案 2 :(得分:2)
假设你这样做:
Scanner scanner = new Scanner(new File("/file/does/not/exist"));
并且构造函数抛出FileNotFoundException
。首先要注意的是构造函数不返回Scanner
对象。相反,new
表达式将异常终止,并且scanner
的分配不会发生。控制最终会在异常的某个处理程序中结束,因为它超出了范围,因此无法引用scanner
。
所以回答你的问题:
如果错误实际被抛出,扫描程序对象是否会关闭,或者在处理异常时我是否仍然必须这样做?
如果构造函数抛出FileNotFoundException
,则Scanner
没有close()
个对象......所以您不需要关闭它。
但是,根据您编写代码的方式,您可能会在不知道是否抛出异常,是否在构造函数中抛出或构造函数完成之后到达处理程序或finally
块。处理这个问题的方法取决于您使用的Java版本。在Java 7之前,这个成语就像是@Sangeeth的答案。对于Java 7及更高版本,您可以这样写:
try (Scanner scanner = new Scanner(new File(path))) {
//your code here
} catch (FileNotFoundException e) {
//log it
}
请注意"尝试使用资源"语法有一个隐式finally
,它会在close()
开头声明的每个(autocloseable)资源上自动调用try
。这使您免除了在各种可能的成功和失败案例中关闭资源的繁琐代码的责任。
事实上,我们可以更深入地考虑这个问题。 Scanner
构造函数调用FileInputStream
来打开文件,这就是抛出FileNotFoundException的地方。反过来,这将调用本机open
方法来实际打开文件。如果在这个过程中出现问题(并抛出异常),那么它就是构造函数'在允许异常传播之前,确保释放任何资源(例如本地流已关闭)的责任。
它必须以这种方式工作,因为失败的构造函数不会返回任何内容,并且他们不能依赖堆栈中的某些东西知道如何在特定的异常处理程序中释放资源。
答案 3 :(得分:0)
我猜您应该关闭 finally 块中的扫描仪对象,无论您是否捕获到异常。