Java未报告的异常
在学习Java时,我经常偶然发现这个错误。它是这样的:Java未报告的异常
未报告的异常java.io.FileNotFound异常;必须被捕获或宣布被抛出。
java.io.FileNotFound只是一个例子,我见过很多不同的东西。在这种特殊情况下,代码导致错误是:
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));
错误总是会消失,代码编译&运行成功,一旦我把声明try/catch块内。有时候对我来说已经够好了,但有时候并非如此。
首先,我学习的示例并不总是使用try/catch,但显然应该工作。
什么更重要,有时当我把整个代码放入try/catch中时,它根本无法工作。例如。在这种特殊情况下,我需要out.close(); in finally {} block;但是如果上面的声明在之内,请尝试{},终于{} does not“see”out因此无法关闭它。
我的第一个想法是import java.io.FileNotFound;或其他相关的例外,但它没有帮助。
你指的是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
它(或者声明它的调用者可以处理它等等)。
Java的检查异常使程序员解决这样的问题。 (在我看来,这是一件好事,即使清除地毯下的错误也更容易。)
如果发生故障,您应该采取适当的措施。通常,处理应该在与引发异常的位置不同的层。
资源应正确处理的,采取以下形式:
acquire();
try {
use();
} finally {
release();
}
切勿将acquire()
try块中。千万不要在acquire()
和try
之间放置任何东西(除了简单赋值之外)。不要尝试在单个finally
块中释放多个资源。
所以,我们有两个不同的问题。不幸的是,Java语法混合了这两者。写这样的代码正确的方法是:
try {
final FileOutputStream rawOut = new FileOutputStream(file);
try {
OutputStream out = new BufferedOutputStream(rawOut);
...
out.flush();
} finally {
rawOut.close();
}
} catch (FileNotFoundException exc) {
...do something not being able to create file...
} catch (IOException exc) {
...handle create file but borked - oops...
}
谢谢,我总是欣赏良好的编码实践建议。 – Sejanus 2010-01-20 09:56:35
为什么不把try放在try块中? – 2013-02-14 21:18:13
@BrianGordon如果你将获取放在'try'中,即使获取失败,你也会运行释放部分('finally'),这是错误的。 /现在你可以尝试一些代码来检查获取是否成功,然后才能运行该版本。但是经验表明通常写入不正确(而且显然没有经过测试),所以你不妨去更简单的代码。 – 2013-02-16 16:52:48
Sun网站上的一些信息:[例外](http://java.sun.com/docs/books/jls/second_edition/html/exceptions.doc。 html) – garyj 2010-01-19 06:40:12