2010-04-13 69 views
6

我可以使用try-catch循環「修復」下面的異常,但我無法理解原因。Java:什麼是BufferedReader的readLine()中的IOEXceptions?

  1. 爲什麼「in.readLine()」部分連續點燃IOExceptions?
  2. 拋出這種例外的真正目的是什麼,目標可能不僅僅是更多的副作用?

碼和的IOExceptions

$ javac ReadLineTest.java 
ReadLineTest.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown 
    while((s=in.readLine())!=null){ 
        ^
1 error 
$ cat ReadLineTest.java 
import java.io.*; 
import java.util.*; 

public class ReadLineTest { 
public static void main(String[] args) { 
    String s; 
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
    // WHY IOException here? 
    while((s=in.readLine())!=null){ 
    System.out.println(s); 
    } 
} 
} 
+2

太陽異常教程:http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html – BalusC 2010-04-13 13:09:42

回答

7

基本的想法是,一個BufferedReader委託給不同類型的Reader,所以它傳遞了這個異常。

這種不同類型的Reader可以從某種可變外部資源讀取,比如在FileReader的情況下是文件系統。文件系統讀取可能會因多種原因而失敗。 (如果讀者從網絡流獲取其基礎數據,情況會更糟糕)。該文件可能會被刪除(取決於所涉及的文件系統和操作系統)。

因爲你無法預測代碼會發生什麼,所以你會得到一個檢查過的異常 - 問題是API告訴你應該考慮這樣的事實,即即使沒有任何錯誤你的代碼。

1

IOException異常是一個checked exception。你必須抓住它,或者把它扔到你的調用方法。檢查異常是由外部參與者引起的,如丟失的文件,失敗的磁盤或任何在程序代碼中無法恢復的內容。

但是,像ArrayIndexOutofBoundsException這樣的Unchecked異常是由程序中的錯誤邏輯引起的。您可以通過在有缺陷的代碼之外使用if條件來破壞它(例如currIndex> array.length)。在檢查異常的情況下沒有這樣的規定

1

如果I/O發生異常情況(例如流源不再可用),則會拋出此錯誤。

在這種情況下,您的程序應該能夠恢復。無論是通過重新閱讀來源,或通過使用一些默認值,或通過提醒用戶有關問題。

你被迫爲catch它,因爲它是一個檢查異常,你應該能夠從這些異常中恢復。

當然,你可以選擇聲明當前使用的方法throws這個調用方法的例外,但是你必須最終捕獲它(或者讓它直接打印到主方法上,當它簡單地打印在控制檯和程序執行停止)

+2

@downvoter - 讓我解決你認爲這個答案是錯誤的。 – Bozho 2010-04-13 13:19:54

2

BufferedReader.readLine()被聲明爲可能拋出一個異常,請參閱:http://java.sun.com/j2se/1.3/docs/api/java/io/BufferedReader.html#readLine()

您也需要抓住它,或宣佈你的主要方法拋出IOException異常。

即,或者這樣做:

try { 
    while((s=in.readLine()) != null){ 
     System.out.println(s); 
    } 
} catch(IOException e) { 
    // Code to handle the exception. 
} 

或者

public static void main(String[] args) throws IOException { ... 
3
  1. 它不會 「汽車無點燃」 出來的,它只是可能每次調用它的時候把他們。在你的情況下,如果它拋出一些東西,這意味着你的標準輸入出現了嚴重錯誤。
  2. 目標是確保您,使用API​​的程序員處理問題,因爲它通常被認爲是可恢復的問題 - 儘管在您的特殊情況下它會對您的整個程序造成致命的影響。
0

使用Scanner讀取文件(或其他類型的輸入)在中/大規模情況下可能效率非常低。如果您在閱讀數千或數百行代碼時遇到性能問題,我強烈建議您使用BufferedReader類代替。的BufferedReader的使用以讀取來自System.in線的一個例子顯示在下面:

public static void main(String[] args) throws Exception { 

    String line = null; 
    BufferedReader br = new BufferedReader (new InputStreamReader(System.in)); 

    try { 
     /* This is protected code. If an problem occurs here, catch block is triggered */ 
     while ((line = br.readLine()) != null){ 
      System.out.println(line); 
     } 
    } 
    catch (IOException e){ 
     throw new IOException("Problem reading a line",e); 
    } 
} 

IOException的應try/catch塊,以便可以觸發使用每當內部的「例外」行爲try患有受保護的代碼,諸如錯誤。 Java有他自己的例外情況,當類似的情況發生時被拋棄。例如,當您定義大小爲n的數組a並嘗試訪問代碼中某處的位置a[n+1]時,會丟棄ArrayIndexOutOfBoundsException。 與ArrayIndexOutOfBoundsException一樣,還有很多其他Exception類可以使用您自己的消息來引發和自定義。 適用於異常的代碼應放置在try塊的受保護區域中。當該塊發生異常時,異常將在它的catch塊中處理。

看看您不需要構建if/else語句來預測錯誤情況併爲每種情況拋出異常。您只需將trycatch區塊之間的可能異常情況關聯起來即可。有關安全編程的更多信息,請參閱try/catch blocks

相關問題