您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Java接口中的可选方法

Java接口中的可选方法

这里的答案似乎有很多混乱。

Java语言要求接口中的每种方法都必须由该接口的每种实现来实现。期。 说“收藏是一个例外”,这表明对这里的实际情况非常模糊。

重要的是要意识到接口的符合性分为两个层次:

Java语言可以检查的内容。这几乎可以归结为:每个方法都有 一些 实现吗?

实际履行合同。也就是说,该实现是否执行界面中的文档所述的内容

编写良好的接口将包括文档,这些文档确切解释了实现的期望。您的编译器无法为您检查。您需要阅读文档,然后按他们说的做。如果您没有按照合同的约定执行操作,那么就编译器 而言,您将拥有该接口的实现,但这将是有缺陷/无效的实现。

在设计Collections API时,约书亚·布洛赫(Joshua Bloch)决定,除了拥有非常细粒度的界面来区分不同的集合变体(例如:可读,可写,随机访问等)之外,他只会拥有非常粗糙的接口集,主要是CollectionListSetMap,然后记录某些操作为“可选”。这是为了避免细粒度接口导致的组合爆炸。来自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是aRuntimeException,就编译器而言,您可以将其从任何方法实现中抛出。例如,您可以从实现中抛出它Collection.size()。但是,这样的实现会违反合同,因为的文档Collection.size()没有说这是允许的。

另外:Java的Collections API使用的方法有些争议(但是现在可能比第一次引入时要少)。在理想情况下,接口将 没有 可选操作,而将使用细粒度的接口。问题在于Java不支持推断的结构类型或交集类型,这就是为什么尝试以“正确的方式”做事最终变得非常笨拙的原因是集合。

java 2022/1/1 18:14:20 有645人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶