首先,请注意第 29 条实际上是关于使用参数化键的一般概念:
但是,有时您需要更大的灵活性。例如,一个数据库行可以有任意多列,如果能够以类型安全的方式访问所有列,那就太好了。幸运的是,有一种简单的方法可以实现这种效果。这个想法是参数化key而不是container。
本项目的目的是证明您可以通过更多方式使用泛型,而不仅仅是通过参数化类型。异构容器模式只是这种技术的一个例子。诚然,该项目可以通过一个更好的标题来更清楚地说明这一点,例如“在使用任意数量的类型时考虑使用参数化方法来强制类型安全”。
该项目演示的异构容器模式专门用于您希望将某些类型与每种类型的特定实例相关联的情况。Guava包含了这种模式的实现及其ClassToInstanceMap
类型(更多细节)。它们还提供了更强大TypeToInstanceMap
的支持任意泛型类型(例如List<String>
)的功能,但 API 确实略显繁琐。
所有这一切都是说,没有什么能阻止您创建一个支持给定类型的多个实例的类似结构的类。我们可以轻松地获取ClassToInstanceMap
API 并创建一个ClassToInstanceMultimap
类型(扩展 Guava 的Multimap
API):
public interface ClassToInstanceMultimap<B> extends Multimap<Class<? extends B>, B> {
/**
* Returns the values the specified class is mapped to, or an empty collection if no
* entries for this class is present. This will only return a value that was
* bound to this specific class, not a value that may have been bound to a
* subtype.
*/
<T extends B> Collection<T> getInstances(Class<T> type);
/**
* Stores an entry mapping the specified class to the specified value. Does <i>not</i>
* associate this value with any of the class's supertypes.
*
* @return {@code true} if the method increased the size of the multimap, or
* {@code false} if the multimap already contained the key-value pair and doesn't allow
* duplicates
*/
<T extends B> T putInstance(Class<T> type, T value);
}
Guava 目前不包含这样的接口,但其实现ClassToInstanceMap
非常简单,因此您可以轻松创建自己的ClassToInstanceMultimap
实现。