2014-12-05 29 views
1

在我正在使用Java編寫的程序中,我必須從文件中讀取數據。數據被格式化,以便每行包含構建新對象的所有必要信息。當我分析數據,我有一個代碼塊,看起來是這樣的:Java風格:捕捉一堆稍微不同的錯誤

String[] parts = file.nextLine().split(","); 

String attr1 = parts[0]; 
int attr2, attr3; 
try{ 
    attr2 = Integer.parseInt(parts[1]); 
} catch (NumberFormatException ex){ 
    System.out.println("Could not parse attr2, got " + parts[1] + "."); 
    return; 
} 
try{ 
    attr3 = Integer.parseInt(parts[2]); 
} catch (NumberFormatException ex){ 
    System.out.println("Could not parse attr3, got " + parts[2] + "."); 
    return; 
} 
ClassA attr4 = null, attr5 = null, attr6 = null; 
try{ 
    ... 
} catch (SomeExceptionType ex){ 
    System.out.println("Could not parse attr4, got " + parts[3] + "."); 
} 
... 

,我發現自己一遍又一遍地重複同樣的簡單try塊。在試圖緩和局勢,堅持DRY原則多一點,我介紹了一些attempt方法:

int attr2 = attemptGetInt(parts, 1, "attr2"); 
int attr3 = attemptGetInt(parts, 2, "attr3"); 
ClassA attr4 = attemptGetClassA(parts, 3, "attr4"); 
... 

// Somewhere in the class 

public int attemptGetInt(String[] parts, int index, String name) throws SomeOtherException1{ 
    try{ 
     return Integer.parseInt(parts[index]); 
    } catch (NumberFormatException ex){ 
     throw new SomeOtherException1("Could not parse " + name + ", got " + parts[index] + "."); 
    } 
} 

public ClassA attemptGetClassA(String[] parts, int index, String name) throws SomeOtherException2{ 
    try{ 
     return ... 
    } catch (SomeExceptionType ex){ 
     throw new SomeOtherException2("Could not parse " + name + ", got" + parts[index] + "."); 
    } 
} 
... 

即使這種感覺怪怪的,但因爲有很多不同類型的我要,所有返回每種都有相同但略有不同的代碼,每次都需要捕獲一個稍微不同的錯誤(即,我必須創建一個attemptGetClassBattemptGetClassC等等,每次都有類似的代碼)。

有沒有像這樣編寫代碼的優雅方式?

+0

不是。查看[PrintStream](https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html)並記下有多少種打印方法。不幸的是,真的沒有什麼好方法。 – 2014-12-05 03:39:23

回答

1

如果您可以控制輸入文件的格式,則可能希望將其更改爲帶有模式的XML。這樣解析器本身就負責處理這種類型的檢查。

但是,從問題的性質,我認爲格式是固定的。在這種情況下,我會建議將語法檢查和解析分解爲每行的單獨步驟。

執行語法檢查的簡單方法是使用正則表達式。相當複雜的語法可以用正則表達式編碼,因此除非文件包含某種嵌套(在這種情況下DEFINITELY使用XML),那麼它應該相當簡單。

解析的第二步應該只會通過異常返回異常:-)您仍然需要捕獲它們,但將它們全部捕獲到一個塊中是非常好的形式,因爲它應該僅在調試時使用:in正常操作的語法檢查將在此步驟之前捕獲錯誤。

我認爲這個設計更直觀明瞭。如果您特別想單獨報告每個錯誤,則它可能在錯誤報告中存在缺陷。在這種情況下,您需要首先將字符串分解爲子字符串(例如,使用Scanner),然後使用語法檢查每個子字符串。

作爲最後的註釋,意見不盡相同,但我的個人偏好不是對正常操作中發生的情況使用異常處理。他們不適合那個(在我看來)。更好地做我在這裏建議的:有明確的代碼在處理之前檢查錯誤條件,然後對通常不會發生的事情使用異常。