2012-12-02 108 views
2

所以,我有一個叫做Puzzle的類,以及兩個(相關的)構造函數。一個構造函數不接受參數,另一個接受int,但也會引發異常。其基本思路是這樣的:如何在構造函數中避免這種不必要的throws語句?

public class Puzzle { 
    // Fields, methods, etc. 
    public Puzzle() { 
     this(3); 
    } 

    public Puzzle(int n) throws Exception { 
     if (n < 2) throw new Exception(); 

     // More constructor code 
    } 
} 

當然,這並不能編譯,因爲接受一個int的構造函數拋出異常,並且不ARGS構造不處理或拋出異常。但是,由於很明顯看到異常永遠不會被拋出(在構造函數的主體中沒有更多的異常),所以這應該沒有關係。我可以只使用一個空白try-catch語句是這樣的:

public Puzzle() { 
    try { 
     this(3); 
    } catch (Exception e) { 
     // Never happens 
    } 
} 

這裏的問題是,調用this(3)不再是構造函數的第一個語句,所以它不會編譯。似乎我必須用throws子句標記此構造函數,即使我知道它永遠不會拋出異常。這真的很煩人,因爲調用代碼將需要有不必要的try-catch塊,否則他們將不得不拋出異常。有沒有一種優雅的方式可以解決這個問題?我知道我可以輕鬆地複製和粘貼一些代碼,但這與OOP中的所有聖潔內容背道而馳。有任何想法嗎?

回答

6

使用運行時異常。具體來說,IllegalArgumentException是爲此設計的。

+0

這是最簡單的解決方案,它需要最少的修改。謝謝! – brenns10

+0

因爲它永遠不會發生,所以使用AssertionError。存在非法參數時使用IllegalArgumentException。 –

+0

@PeterLawrey--不理解你的論點。我將AssertionError與違反應該永遠不會發生的內部不變量(也就是說,您的代碼中存在邏輯錯誤)相關聯。 – jtahlborn

1

打破了在構造函數中的私人初始化方法的代碼:

public class Puzzle { 
    // Fields, methods, etc. 
    public Puzzle() { 
     construct(3); 
    } 

    public Puzzle(int n) throws Exception { 
     if (n < 2) throw new Exception(); 

     construct(n);   

    } 

    private void construct(int n) { 
     // More constructor code 
    } 
} 
+0

一個可行的想法,雖然私人初始化是一個痛苦的原因,你不能使用最終成員。 – jtahlborn

+0

@jtahlborn是真的。你的回答是一個更好的方法來做到這一點。 –

+0

+1,但可行的解決方案。我不敢相信我沒有想到這樣的事情。 – brenns10

相關問題