Java接口中的可选方法
据我了解,如果您使用Java实现接口,则实现该接口的子类必须使用该接口中指定的方法。
我注意到在某些接口(例如Collection接口)中,有一些方法被注释为可选方法,但这究竟意味着什么?我觉得接口中指定的所有方法都需要吗?
回答:
这里的答案似乎有很多混乱。
Java语言要求接口中的每种方法都必须由该接口的每种实现来实现。期。 说“是一个例外”,这表明对这里的实际情况非常模糊。
重要的是要意识到接口的符合性分为两个层次:
Java语言可以检查的内容。这几乎可以归结为:每个方法都有 一些 实现吗?
实际履行合同。也就是说,该实现是否执行界面中的文档所述的内容?
编写良好的接口将包括文档,这些文档确切解释了实现的期望。您的编译器无法为您检查。您需要阅读文档,然后按他们说的做。如果您没有按照合同的约定执行操作,那么就
编译器 而言,您将拥有该接口的实现,但这将是有缺陷/无效的实现。
在设计Collections API时,约书亚·布洛赫(Joshua
Bloch)决定,除了拥有非常细粒度的界面来区分不同的集合变体(例如:可读,可写,随机访问等)之外,他只会拥有非常粗糙的接口集,主要是
Collection
,List
,Set
和Map
,然后记录某些操作为“可选”。这是为了避免细粒度接口导致的组合爆炸。来自Java
Collections
API设计常见问题解答:
为了详细说明问题,假设您想在层次结构中添加可修改性的概念。您需要四个新接口:ModifiableCollection,ModifiableSet,ModifiableList和ModifiableMap。以前简单的层次结构现在变成了混乱的层次结构。另外,您需要一个新的Iterator接口以用于不可修改的Collection,其中不包含remove操作。现在您可以取消UnsupportedOperationException吗?不幸的是没有。
考虑数组。它们执行大多数List操作,但不执行删除和添加操作。它们是“固定大小”列表。如果要在层次结构中捕获此概念,则必须添加两个新接口:VariableSizeList和VariableSizeMap。您不必添加VariableSizeCollection和VariableSizeSet,因为它们与ModifiableCollection和ModifiableSet相同,但是出于一致性考虑,您可能仍选择添加它们。另外,您还需要各种不支持添加和删除操作的ListIterator以及无法修改的List。现在,我们有多达十个或十二个接口,外加两个新的Iterator接口,而不是原来的四个。我们完了吗?没有。
考虑日志(例如错误日志,审核日志和可恢复数据对象的日志)。它们是自然的仅追加序列,支持所有列表操作(除去和设置(替换))。他们需要一个新的核心接口和一个新的迭代器。
与不可变集合相比,不可变集合又如何呢?(即,客户端无法更改的集合,并且由于其他任何原因也不会更改)。许多人认为这是最重要的区别,因为它允许多个线程同时访问集合而无需同步。将这种支持添加到类型层次结构中还需要四个接口。
现在我们有多达二十个左右的接口和五个迭代器,并且几乎可以肯定的是,实际上仍然有一些集合不能完全适合任何一个接口。例如,Map返回的集合视图是自然的仅删除集合。另外,有些集合会根据其值拒绝某些元素,因此我们仍然没有消除运行时异常。
说完所有内容后,我们认为通过提供很少的一组核心接口(可能会抛出运行时异常)来回避整个问题,这是合理的工程折衷方案。
当Collections
API中的方法被记录为“可选操作”时,这并不意味着您可以只将方法实现留在实现中,也不意味着您可以使用空的方法主体(一方面,很多他们需要返回结果)。相反,这意味着一个有效的实现选择(仍然符合合同的选择)是抛出UnsupportedOperationException
。
注意,因为UnsupportedOperationException
是a
RuntimeException
,就编译器而言,您可以将其从任何方法实现中抛出。例如,您可以从实现中抛出它Collection.size()
。但是,这样的实现会违反合同,因为的文档Collection.size()
没有说这是允许的。
另外:Java的Collections API使用的方法有些争议(但是现在可能比第一次引入时要少)。在理想情况下,接口将 没有
可选操作,而将使用细粒度的接口。问题在于Java不支持推断的结构类型或交集类型,这就是为什么尝试以“正确的方式”做事最终变得非常笨拙的原因是集合。
以上是 Java接口中的可选方法 的全部内容, 来源链接: utcz.com/qa/404612.html