2013-09-22 258 views
2

我有一個構造函數,它在同一個類中調用另一個構造函數。問題是我想捕獲異常並將它們向前拋出到調用第一個構造函數的方法。但是Java不允許這樣做,因爲構造函數調用必須是構造函數中的第一條語句。從構造函數調用構造函數並捕獲異常

public Config(String fn) throws IOException, ExcFormattingError { 
    theFile = fn; 
    try { cfRead(); } 
    catch(FileNotFoundException e) { 
     //create a new config with defaults. 
     theConfig = defaultConfig(); 
     create(); 
    } catch (IOException e) { 
     throw new IOException(e); 
    } catch (ExcFormattingError e) { 
     throw new ExcFormattingError(); 
    } 

    fixMissing(theConfig); 
} 

public Config() throws IOException, ExcFormattingError { 
    try { 
     //Line below is in error... 
     this("accountmgr.cfg"); 
    } catch (IOException e) { 
     throw new IOException(e); 
    } catch (ExcFormattingError e) { 
     throw new ExcFormattingError(); 
    } 
} 

如果有人能解釋我該如何做到這一點很好。獎金是知道爲什麼語言必須這樣做,因爲這總是很有趣。

+3

爲什麼你抓住例外呢?如果你不抓住他們,他們只會回到所謂的第一個構造者身上。 –

+0

請參閱http://stackoverflow.com/a/1168356/1729686爲什麼需要先調用this()和super()。 – Liam

回答

3

在構造函數中你不需要那些try-catch塊(事實上,你不能在那裏寫出它,就像你已經想到的那樣)。所以,你的構造函數更改爲:

public Config() throws IOException, ExcFormattingError { 
    this("accountmgr.cfg"); 
} 

事實上,在構造函數中catch塊幾乎沒有做任何富有成效。它只是重新創建一個相同異常的實例,並拋出它。這實際上並不需要,因爲如果引發異常,它將自動傳播到調用者代碼,您可以在其中處理異常。

public void someMethod() { 
    Config config = null; 
    try { 
     config = new Config(); 
    } catch (IOException e) { 
     // handle it 
    } catch (ExcFormattingError e) { 
     // handle it 
    } 
} 

說了這麼多,這是很少一個好主意,從構造函數拋出一個checked異常,更糟糕的處理它們在調用者的代碼。
如果引發異常,並在調用方法中處理它。然後你簡單地忽略了你的實例沒有完全初始化的事實。進一步處理該實例將導致一些意外行爲。所以,你應該避免它。