2010-08-22 104 views
10

如何從枚舉構造函數中拋出異常?例如:如何從枚舉構造函數中拋出異常?

public enum RLoader { 
    INSTANCE; 
    private RLoader() throws IOException { 
    .... 
    } 
} 

產生錯誤

未處理的異常類型爲IOException

+6

你爲什麼要這麼做?對我來說,這聽起來像是濫用枚舉概念。枚舉值應該是常量,其創建不依賴於任何東西。即使技術上你可以做到這一點(通過拋出未經檢查的異常而不是已檢查過的異常),我建議你修改你的設計。如果你想通過這個枚舉來實現一個Singleton,最好是用普通的類來實現它。 – 2010-08-22 23:33:16

+2

我正在實現一個Singleton,但是如何將它作爲一個普通的類手動實現會更好?我仍然必須從靜態初始化器調用的代碼中引發異常。 您可以從枚舉構造函數中拋出未經檢查的異常。 – tukushan 2010-08-22 23:53:26

+0

有一些* icky *關於通過訪問枚舉值來拋出異常。當它是一個單例getInstance()方法時不那麼糟糕。 – 2010-08-22 23:55:30

回答

15

因爲實例在靜態初始化創建,拋出的ExceptionInInitializerError代替。

+5

儘管這是一個可能的解決方案,但我認爲這樣解決問題並不合理。 – 2010-08-22 23:53:44

0

該方案無法工作。

您正試圖從構造函數中拋出一個選中的Exception

該構造函數由INSTANCE enum條目聲明調用,因此檢查的異常無法正確處理。

另外,在我看來,從構造函數中拋出異常是一種糟糕的風格,因爲構造函數通常不應該做任何工作,尤其是不會創建錯誤。

此外,如果你想拋出一個IOException我假設你想從一個文件初始化某些東西,所以你應該考慮這篇文章dynamic enums

+3

如果從構造函數中拋出異常的風格很糟糕,那麼當你的構造函數的參數之一是無效的並且會阻止你的類運行時,你會怎麼做?我更喜歡通過拋出異常來快速失敗,這樣我就可以獲得有意義的堆棧跟蹤。話雖如此,我同意你的觀點,OP不應該試圖在**枚舉的構造函數中引發異常。 – 2010-08-22 23:57:43

+0

@Kirk Woll:我更喜歡使用確保參數有效性的工廠方法。此外,我主要關注檢查異常,RuntimeException將是發送IMO驗證錯誤的更好方式。 – 2010-08-23 00:00:50

+2

對所有對象實例化獨家使用工廠方法?哦,可憐的新人**。 :) – 2010-08-23 00:05:45

3

我有一種情況,我想在某些設置類中使用枚舉作爲鍵。數據庫將存儲一個字符串值,允許我們改變枚舉常量,而不必去修改數據庫(有點難看,我知道)。我想在枚舉的構造函數中拋出一個運行時異常作爲警告字符串參數長度的一種方法,以避免觸碰數據庫,然後在我可以輕鬆檢測到它時自動獲取約束違規。

public enum GlobalSettingKey { 
    EXAMPLE("example"); 

    private String value; 

    private GlobalSettingKey(String value) { 
     if (value.length() > 200) { 
      throw new IllegalArgumentException("you can't do that"); 
     } 
     this.value = value; 
    } 

    @Override 
    public String toString() { 
     return value; 
    } 
} 

當我爲此創建一個快速測試時,發現拋出的異常不是我的,而是一個ExceptionInInitializerError。

也許這是愚蠢的,但我認爲這是一個相當有效的方案,想要在靜態初始化器中引發異常。

+2

但是原來的異常與ExceptionInInitializerError鏈接在一起,所以如果你對它調用'getCause()',你會得到原始的異常。 – shrini1000 2012-04-19 06:24:54

相關問題