2017-02-21 106 views
5

最近我遇到此代碼。在接口默認方法中拋出異常

public interface CustomerQueryService {  
    default Customer getCustomerById(long id) { 
     throw new NotImplementedException(); 
    } 
} 

事後證明,這是該項目的一般慣例。 它被認爲是一種好的做法嗎?

+2

因此,雖然您概述的用法通常是可以接受的(這是「可選方法」慣用法),但在您的項目中這是「一般慣例」的事實是一個巨大的尖叫紅旗。爲了說明這一點,我僅僅使用了這種模式很少的幾次(例如,'Iterator.remove()')。要看到它經常用作「一般約定」,幾乎肯定會過度使用。 –

+2

更一般地說,定期使用這種約定實際上是將「實現接口」從靜態類型屬性降級爲動態類型屬性。由於他們有理由相信「實現Foo」真正意味着「實現Foo」,所以這總會在毫無戒心和不值得的用戶手中爆炸。真正的選擇性是罕見的;像這樣對待它。 –

+1

@BrianGoetz並備案;我感到非常榮幸在您的面前;-) – GhostCat

回答

10

可以從here開始,看看Brian的「代理父親」之一Brian Goetz如何說「如何使用默認方法」。

因此,根據「對書」;你可以像你的例子一樣使用它們:爲被視爲「可選」的方法拋出異常。但那意味着:你已經有了一些方法;並且你正在添加新的。

main將缺省方法添加到Java語言的目的是爲了允許對現有接口進行不中斷的增強。它們是而不是,意思是用作某種「mixin」/多繼承/特徵提供結構。

但除此之外:在你的榜樣,你有一個新的接口 ...只有有一個方法。我認爲這不屬於這些「預定用途」。

另一方面,不要太多「關於書籍」。當整個團隊同意「這就是我們所做的」,每個人都理解併購買到這一點;爲什麼不?!

但有一點需要說明......我的C++的同事有一個嚴格政策:它們允許恰好一個實現繼承樹中的任何抽象方法的;因爲它是非常難調試時出現問題當你在看錯誤執行某些方法。現在我們可以在Java中繼承默認方法了......調試問題可能對於我們來說同樣變得更困難。所以要小心如何使用這些東西!

長話短說:如果大部分開發團隊認爲這是一種有益的做法,這是一個很好的做法。如果不是,那不是。

+2

我同意,但我建議通過引用來源來改善適用情況。 – Mena

6

我會說這是壞的,因爲異常類型和它是項目慣例的報告。

NotImplementedException

NotImplementedException代表在這裏筆者還沒有在程序中的這一點上實現邏輯的情況下。這可以充當基於TODO標記的異常。

因此,這是一種懶惰的方式,爲所有CustomerQueryService中的方法提供實現,只是爲了在運行時找出尚未編寫它的方法。

注意UnsupportedOperationException可能是一些案件中可以接受的案例,但這兩個案例都不是一個很好的「約定」。

+0

@Loc好的,只是一個巧合,downvote與你的答案完全相同。 – weston