2011-07-25 30 views
11

我的團隊正在清理我們的使用throws Exception,並刪除或替換它們,除了特定的例外。將泛型用於異常是明智的嗎?

常見的拋出是因爲找不到實體。我們應該爲每個實體類拋出通用NotFoundException或特定SomeClassNotFoundException

如果我們應該拋出一個特定的異常,我們應該爲每個實體類型創建一個特定的Exception類嗎?我們可以安全地使用泛型嗎?像這樣class NotFoundException<T extends EntityBaseClass> extends Exception,然後構造函數負責聲明我們正在處理的實體類型?

如果我們應該拋出一個特定的異常而不使用泛型,那麼這些異常是否應該擴展或實現NotFoundException抽象類或接口?

回答

11

的問題

我們是否應該爲每個實體類型創建一個特定的異常類簡單的試金石?

是否存在,我們需要編寫一個catch條款,將捕獲「未找到」異常由某些類X 並沒有拋出任何其他類的情況?

如果答案是「是」,那麼單獨的ClassXNotFoundException是有保證的;否則,它可能不是。

至於您的問題的後半部分,該語言不允許將異常類型用於泛型。

20

它不允許做例外通用 - 它不會編譯(JLS §8.1.2):

這是一個編譯時錯誤,如果一個泛型類是Throwable的

直接或間接的子類

由於泛型的類型參數在運行時被擦除,因此無法區分catch子句中具有不同類型參數的泛型異常,因此不支持泛型異常。所以,你實際上沒有選擇使用泛型異常。

5

我們應該爲每個實體類型創建一個特定的Exception類嗎?

如果您的代碼的調用者可以合理地從找到實體定義的失敗中恢復,並且可以從每種實體類型採取不同的恢復策略中受益,那麼是的。否則不。

我們可以安全使用泛型嗎?像這個類一樣,NotFoundException擴展了Exception,然後構造函數負責聲明我們正在處理的實體類型?

它不會幫助您的代碼的調用者切換與失敗相關的實體類型。

即使你由於類型擦除定義異常類型MyParameterizedException<T>然後,調用者不能做

try { 
    callYourCode(); 
} catch (MyParameterizedException<TypeA> ex) { 
    // some handling code 
} catch (MyParameterizedException<TypeB> ex) { 
    // some different handling code for type b 
} 

因爲類型擦除它看起來像

try { 
    callYourCode(); 
} catch (MyParameterizedException ex) { 
    // some handling code 
} catch (MyParameterizedException ex) { 
    // some different handling code for type b 
} 

和第二catch塊將無法訪問的代碼,因此將在編譯時被javac拒絕。第一個catch塊將被輸入爲b類型並鍵入一個實體(以及其他任何類型)。

如果我們應該拋出一個特定的異常而不使用泛型,那麼這些異常是否應該擴展或實現NotFoundException抽象類或接口?

如果你的代碼的調用者會感到驚訝,如果他們沒有那麼是的。

如果您的代碼的調用者將受益於由處理其他NotFoundException的代碼處理實體失敗,那麼是的。

如果您的代碼的調用者可能不希望找到與其他NotFound條件相同的方式處理的實體類型定義失敗,則不會。

0

我想每個人的答案都是說你不需要特定的例外。我正在研究Hibernate如何定義沒有發現異常。我發現EntityNotFoundException我會補充說,你甚至不應該創建自己的異常,只需重用這一個。它擴展了RuntimeException,這意味着你不會強迫人們捕捉它。但是如果你想要的話,你可以在J2EE中重用一個現有的類。這總比編寫新代碼好。

5

而不是使用:

public Class EntityNotFoundException<T extends EntityBaseClass> extends Exception { 

} 

你應該使用:

public Class EntityNotFoundException extends Exception { 
    private Class<? extends EntityBaseClass> clazz; 

    public EntityNotFoundException(Class<? extends EntityBaseClass> clazz) { 
     this.clazz = clazz; 
    } 

    . . . 
} 

這樣你就可以保持到正在產生異常的實體類型的引用。要拋出這樣的異常,你可以使用一個:

throw new EntityNotFoundException(Customer.class); 

編譯器驗證客戶是延伸EntityBaseClass。

+0

要注意的一點是,EntityNotFoundException是javax.persistance.EntityNotFoundException的重複名稱。 –

相關問題