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