2008-10-07 56 views
8

如果我有一個類需要實現一個接口,但該接口上的一個或多個方法在這個特定類的上下文中沒有意義,我做?無法實現的接口方法的正確行爲

例如,假設我正在實現一個適配器模式,我想創建一個包裝類,它通過包裝一些不可變對象並將其數據作爲鍵/值對公開,實現java.util.Map。在這種情況下,put和put方法都沒有意義,因爲我無法修改底層對象。所以問題是這些方法應該做什麼?

回答

17

任何不能根據接口的語義實現的方法應拋出一個UnsupportedOperationException

+0

UnsupportedOperationException通常是要走的路,除非您知道該方法將被調用,並且您希望更多地使用「不可操作」,在這種情況下,返回null或類似是最好的選擇。 – skaffman 2008-10-07 17:12:25

+0

好吧......看來你在那裏回答了你自己的問題,Mike .. – Sandman 2008-10-07 21:53:30

10

這取決於您的業務案例。 2選項:

使用哪一個更有意義。如果你什麼都不做,你不會遵守界面的合約。但是,拋出運行時異常會對調用代碼造成嚴重破壞。因此,必須根據您將如何使用課程做出決定。如果可能的話,另一個選擇是使用更簡單的或不同的接口。

請注意,Java庫在read-only集合的特定情況下進入異常路由。


下面指出,UnsupportedOperationException是Java集合框架的一部分。如果你的情況不在集合中,並且語義困擾你,你可以推出你自己的 NotImplementedException,或者如果你已經在使用commons-lang,你可以使用 theirs

3

你兩個選擇,實際上只:

  1. 什麼也不做。
  2. 拋出異常。

兩者都有缺點。在第一種情況下,通過使用空方法,您可能會誤導程序員思考您的數據發生了什麼。第二種情況打破了接口中固有的多態性的全部概念。

2

注意UnsupportedOperationException異常僅僅是可以的,因爲Java集合框架中的特定屬性,即實現被允許「偷懶」實現接口的一部分,因爲他們是不可改變的。

所以put()(假設所有的mutator方法做同樣的事情)都可以,但是從size()方法拋出UnsupportedOperationException的Map只會被打破。如果你試圖實現一種不知道它有多大的地圖,你可能會遇到麻煩(儘管有時你可以返回Integer.MAX_VALUE)。

另請注意,UnsupportedOperationException的類文檔說它是Java集合框架的一部分。在集合框架之外,拋出UnsupportedOperationException不是預期的,並且可能導致客戶端代碼無法正常工作。當然,這是一個RuntimeException,但僅僅因爲你可以拋出它並不意味着你的方法會一直工作。

相反,您可以重構界面(也許將它分成兩部分),或者重新思考爲什麼這個類聲稱自己是Foo,因爲它不能完成定義Foos的事情能夠做到。

5

由Java提供的只讀集合在寫操作期間拋出UnsupportedOperationException已經是一個不幸的設計破解。集合類應該使用獨立的只讀和只寫接口編寫,這些接口都由完整的讀寫接口繼承。然後你知道你得到了什麼。