2010-01-19 262 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

相關問題