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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:26:24  来源:igfitidea点击:

Java unreported exception

javaexceptionexception-handling

提问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...
}