Java未报告的exception

在学习Java的时候,我常常偶然发现这个错误。 它是这样的:

未报告的exceptionjava.io.FileNotFoundexception; 必须被逮捕或宣布被抛出。

java.io.FileNotFound只是一个例子,我见过很多不同的东西。 在这种情况下,导致错误的代码是:

OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf"))); 

一旦我把语句放入try / catch块,错误总是消失,代码编译和运行成功。 有时候对我来说已经够好了,但有时却不行。

首先,我从中学习的例子并不总是使用try / catch,显然应该工作。

更重要的是,有时当我将整个代码放在try / catch中时,根本无法工作。 例如,在这种特殊情况下,我需要out.close(); 终于{}块; 但如果上面的语句是在try {}之内 ,那么finally {}不会“看见” 出来 ,因此不能closures它。

我的第一个想法是导入java.io.FileNotFound; 或另一个相关的例外,但没有帮助。

你所指的是检查exception ,这意味着它们必须被声明或处理。 用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块变得更好一些,但在那之前,你会被困在上面。

你也可以让调用者处理exception:

 public void doStuff() throws IOException { InputStream in = new InputStream(...); // do stuff in.close(); } 

虽然即使这样close()也可能被封装在finally块中。

但是上面的函数声明说这个方法可以抛出一个IOException 。 由于这是一个检查的exception,这个函数的调用者将需要catch它(或者声明它,以便调用者可以处理它等等)。

Java的检查exception使得程序员可以解决像这样的问题。 (在我看来,这是一件好事,即使在地毯下扫除虫子也是如此。)

如果发生故障,您应该采取适当的措施。 通常情况下,处理应该在与抛出exception的地方不同的层次上。

资源应该正确处理,forms如下:

 acquire(); try { use(); } finally { release(); } 

不要把try 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... }