无法实现的接口方法的正确行为

时间:2008-10-07 17:10:18

标签: java

如果我有一个需要实现接口的类,但该接口上的一个或多个方法在这个特定类的上下文中没有意义,我该怎么办?

例如,假设我正在实现一个适配器模式,我想通过包装一些不可变对象并将其数据作为键/值对公开来创建一个实现java.util.Map的包装类。在这种情况下,put和putAll方法没有意义,因为我无法修改底层对象。所以问题是这些方法应该做什么?

5 个答案:

答案 0 :(得分:17)

任何根据接口语义无法实现的方法都应抛出UnsupportedOperationException

答案 1 :(得分:10)

这取决于您的商业案例。 2个选项:

使用更有意义的东西。如果你什么也不做,你就不遵守接口的合同。但是,抛出运行时异常会对调用代码造成严重破坏。因此,必须根据您将如何使用该类来做出决定。如果可能,另一种选择是使用更简单或不同的界面。

请注意,在read-only集合的特定情况下,Java库将成为异常路由。

<小时/> 下面指出UnsupportedOperationException是java集合框架的一部分。如果您的情况不在集合中,并且语义困扰您,您可以滚动自己的NotImplementedException,或者如果您已经使用了公共语言,则可以使用theirs

答案 2 :(得分:5)

Java提供的只读集合在写入操作期间抛出UnsupportedOperationException已经是一个不幸的设计攻击。集合类应该使用单独的只读和只写接口编写,这些接口都由完整的读写接口继承。然后你知道你得到了什么。

答案 3 :(得分:3)

你的两个选择真的只是:

  1. 什么都不做。
  2. 抛出异常。
  3. 两者都有缺点。在第一种情况下,通过使用空方法,您可能会误导程序员思考您的数据发生了什么。第二种情况打破了接口中固有的多态性的整个想法。

答案 4 :(得分:2)

请注意,UnsupportedOperationException只是因为Java Collections Framework的特定属性才可以,因为它们是不可变的,所以允许实现“自动”实现接口的一部分。

所以put()很好(假设所有的mutator方法做同样的事情),但是一个从size()方法抛出UnsupportedOperationException的Map就会被破坏。如果你试图实现一种不知道它有多大的地图,你可能会遇到麻烦(尽管有时你可以返回Integer.MAX_VALUE)。

另请注意,UnsupportedOperationException的类文档说它是Java Collections Framework的一部分。在集合框架之外,不期望抛出UnsupportedOperationException,并且可能导致普通的客户端代码不起作用。当然,这是一个RuntimeException,但只是因为你可以抛出它并不意味着你的方法总能工作。

相反,你可以重构接口(可能将它分成两部分),或者重新考虑为什么这个类声称是Foo时明显不是,因为它不能做Foos定义的东西能够做到。

相关问题