2010-01-19 213 views
2

在学习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;或其他相关的例外,但它没有帮助。

+0

Sun网站上的一些信息:[例外](http://java.sun.com/docs/books/jls/second_edition/html/exceptions.doc。 html) – garyj 2010-01-19 06:40:12

回答

5

你指的是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它(或者声明它的调用者可以处理它等等)。

+0

“处理”我想表示尝试/捕获。在这种情况下,“声明”是什么? – Sejanus 2010-01-19 06:41:11

+0

声明的方法在“throws”子句中添加到方法签名中。 – 2010-01-19 07:03:41

+0

现在明白了,谢谢 – Sejanus 2010-01-19 07:29:10

1

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

谢谢,我总是欣赏良好的编码实践建议。 – Sejanus 2010-01-20 09:56:35

+0

为什么不把try放在try块中? – 2013-02-14 21:18:13

+0

@BrianGordon如果你将获取放在'try'中,即使获取失败,你也会运行释放部分('finally'),这是错误的。 /现在你可以尝试一些代码来检查获取是否成功,然后才能运行该版本。但是经验表明通常写入不正确(而且显然没有经过测试),所以你不妨去更简单的代码。 – 2013-02-16 16:52:48