Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
在这个简短但重要的部分中,你将学习一些简单的指导原则,使你的 API 能够与遵循这些指南的所有其他 API 无缝地互操作。从本质上讲,这些规则定义了在集合世界中成为一个好的“公民”需要什么。
如果你的 API 包含需要输入集合的方法,则将相关参数类型声明为集合 接口 类型之一至关重要。永远不要 使用 实现 类型,因为这会破坏基于接口的集合框架的目的,即允许在不考虑实现细节的情况下操纵集合。
此外,你应该始终使用最不具体的类型。例如,不要请求 List
或 Set
如果 Collection
就可以实现。这不是你不应该在输入上要求 List
或 Set
;如果方法依赖于其中一个接口的属性,则这样做是正确的。例如,Java 平台提供的许多算法在输入时需要 List
,因为它们取决于列表是有序的事实。但是,作为一般规则,在输入中使用的最佳类型是最常用的:Collection
和 Map
。
使用返回值比使用输入参数更灵活。返回实现或继承其中一个集合接口的任何类型的对象都可以。这可以是接口之一,也可以是继承或实现这些接口之一的专用类型。
例如,可以设想一个名为 ImageList
的图像处理包,它返回实现 List
的新类的对象。除了 List
操作之外,ImageList
还可以支持任何特定于应用程序似乎很可取的操作。例如,它可能提供 indexImage
操作,该操作返回一个图像包含 ImageList
中每个图形的缩略图图像。值得注意的是,即使 API 在输出上提供了 ImageList
实例,它也应该在输入上接受任意 Collection
(或者可能是 List
)实例。
从某种意义上说,返回值应该具有输入参数的相反行为:最好返回最特定的适用集合接口,而不是最一般的。例如,如果你确定将始终返回 SortedMap
,则应该为相关方法提供 SortedMap
的返回类型,而不是 Map
。SortedMap
实例比普通的 Map
实例构建起来更耗时,而且功能也更强大。鉴于你的模块已投入时间来构建 SortedMap
,因此让用户访问其增强的功能是很有意义的。此外,用户将能够将返回的对象传递给需要 SortedMap
的方法,以及任何接受 Map
的方法。
目前有很多 API 可以定义自己的专用的集合类型。虽然这很不幸,但鉴于 Java 平台的前两个主要版本中没有集合框架,这是生活中的事实。假设你拥有这些 API 中的一个;下面是你可以做的事情。
如果可能,请改进旧版集合类型以实现其中一个标准集合接口。然后,你返回的所有集合将与其他基于集合的 API 平滑地互操作。如果这是不可能的(例如,因为一个或多个预先存在的类型签名与标准集合接口冲突),请定义一个 adapter class (适配器类),它包装一个旧的集合对象,允许它作为标准集合。(Adapter
类是 custom implementation 的示例。)
如果可能,使用遵循输入准则的新调用来改进 API,以接受标准集合接口的对象。此类调用可以与采用旧版集合类型的调用共存。如果这是不可能的,请为遗留类型提供构造函数或静态工厂,该构造函数或静态工厂接受其中一个标准接口的对象,并返回包含相同元素(或映射)的旧集合。这些方法中的任何一种都允许用户将任意集合传递到你的 API 中。