Java未报告的异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2091589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java unreported exception
提问by Sejanus
While learning Java I stumble upon this error quite often. It goes like this:
在学习 Java 时,我经常偶然发现这个错误。它是这样的:
Unreported exception java.io.FileNotFound exception; must be caught or declared to be thrown.
未报告的异常 java.io.FileNotFound 异常;必须被捕获或声明被抛出。
java.io.FileNotFound is just an example, I've seen many different ones. In this particular case, code causing the error is:
java.io.FileNotFound 只是一个例子,我见过很多不同的例子。在这种特殊情况下,导致错误的代码是:
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));
Error always disappears and code compiles & runs successfully once I put the statement inside try/catch block. Sometimes it's good enough for me, but sometimes not.
一旦我将语句放入 try/catch 块中,错误总是消失并且代码编译并成功运行。有时这对我来说已经足够了,但有时却不够。
First, examples I'm learning from do not always use try/catch and should work nevertheless, apparently.
首先,我正在学习的示例并不总是使用 try/catch 并且显然应该可以工作。
Whats more important, sometimes when I put whole code inside try/catch it cannot work at all. E.g. in this particular case I need to out.close();in finally{ }block; but if the statement above itself is inside the try{ }, finally{}doesnt "see" outand thus cannot close it.
更重要的是,有时当我将整个代码放入 try/catch 时,它根本无法工作。例如,在这种特殊情况下,我需要out.close(); 在finally{}块中;但是如果上面的语句本身在try{ }内部,finally{}不会“看到”出来,因此无法关闭它。
My first idea was to import java.io.FileNotFound;or another relevant exception, but it didnt help.
我的第一个想法是导入 java.io.FileNotFound;或其他相关的例外,但它没有帮助。
采纳答案by cletus
What you're referring to are checked exceptions, meaning they must be declared or handled. The standard construct for dealing with files in Java looks something like this:
您所指的是检查异常,这意味着它们必须被声明或处理。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) {
}
}
}
Is it ugly? Sure. Is it verbose? Sure. Java 7 will make it a little better with ARM blocks but until then you're stuck with the above.
丑吗?当然。它很冗长吗?当然。Java 7 会用 ARM 块让它更好一点,但在那之前你会被上面的内容困住。
You can also let the caller handle exceptions:
您还可以让调用者处理异常:
public void doStuff() throws IOException {
InputStream in = new InputStream(...);
// do stuff
in.close();
}
although even then the close()should probably be wrapped in a finallyblock.
尽管即便如此,也close()应该将其包裹在一个finally块中。
But the above function declaration says that this method can throw an IOException. Since that's a checked exception the caller of this function will need to catchit (or declare it so its caller can deal with it and so on).
但是上面的函数声明说这个方法可以抛出一个IOException. 由于这是一个检查异常,这个函数的调用者将需要catch它(或声明它以便它的调用者可以处理它等等)。
回答by Tom Hawtin - tackline
Java's checked exceptions make programmers address issues like this. (That's a good thing in my opinion, even if sweeping bugs under the carpet is easier.)
Java 的检查异常使程序员可以解决这样的问题。(在我看来,这是一件好事,即使扫地毯下的虫子更容易。)
You should take some appropriate action if a failure occurs. Typically the handling should be at a different layer from where the exception was thrown.
如果发生故障,您应该采取一些适当的措施。通常,处理应该在与抛出异常不同的层。
Resource should be handled correctly, which takes the form:
应该正确处理资源,它采用以下形式:
acquire();
try {
use();
} finally {
release();
}
Never put the acquire()within the try block. Never put anything between the acquire()and try(other than a simple assign). Do not attempt to release multiple resources in a single finallyblock.
切勿将 放在acquire()try 块内。永远不要在acquire()and之间放置任何东西try(除了简单的赋值)。不要尝试在单个finally块中释放多个资源。
So, we have two different issues. Unfortunately the Java syntax mixes up the two. The correct way to write such code is:
所以,我们有两个不同的问题。不幸的是,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...
}

