在学习Java的过程中,我经常偶然发现这个错误。它是这样的:
未报告的异常java.io.FileNotFound异常;必须被抓或宣布被抛出。
java.io.FileNotFound只是一个例子,我见过许多不同的例子。在这种特殊情况下,导致错误的代码是:
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));
错误总是消失,代码编译&一旦我将语句放在try / catch块中,就会成功运行。有时它对我来说足够好,但有时候不行。
首先,我正在学习的例子并不总是使用try / catch,显然应该可以工作。
更重要的是,有时当我将整个代码放入try / catch中时,它根本无法工作。例如。在这种特殊情况下,我需要在 finally {} 块中 out.close(); ;但如果上面的陈述本身在 try {} 内,最终{} 不会“看到” out ,因此无法关闭它。
我的第一个想法是导入java.io.FileNotFound; 或其他相关的异常,但它没有帮助。
答案 0 :(得分:10)
您所指的是checked exceptions,这意味着必须声明或处理它们。用Java处理文件的标准结构如下所示:
InputStream in = null;
try {
in = new InputStream(...);
// do stuff
} catch (IOException e) {
// do whatever
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
}
难看吗?当然。它是冗长的吗?当然。 Java 7将使ARM块更好一些,但在此之前你会遇到上述情况。
您也可以让调用者处理异常:
public void doStuff() throws IOException {
InputStream in = new InputStream(...);
// do stuff
in.close();
}
尽管如此,close()
可能应该包含在finally
块中。
但是上面的函数声明说这个方法可以抛出IOException
。由于这是一个已检查的异常,因此该函数的调用者需要catch
它(或声明它以便其调用者可以处理它等等。)
答案 1 :(得分:2)
Java检查的异常使程序员解决这样的问题。 (在我看来,这是一件好事,即使地毯下面的虫子更容易被扫除。)
如果发生故障,您应采取适当的措施。通常,处理应该与抛出异常的层不同。
应正确处理资源,其形式为:
acquire();
try {
use();
} finally {
release();
}
永远不要将acquire()
放在try块中。切勿在{{1}}和acquire()
之间放置任何内容(除了简单的分配)。不要尝试在单个try
块中释放多个资源。
所以,我们有两个不同的问题。不幸的是,Java语法混淆了两者。编写此类代码的正确方法是:
finally