2008-10-07 74 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已经是一个不幸的设计破解。集合类应该使用独立的只读和只写接口编写,这些接口都由完整的读写接口继承。然后你知道你得到了什么。