1. 概述
ClassToInstanceMap<B>
是一种特殊类型的 Map,它将类(Class)与对应的实例(Instance)关联起来。它确保所有键和值都是上界类型 B
的子类型。
ClassToInstanceMap
扩展了 Java 的 Map
接口,并额外提供了两个方法:T getInstance(Class<T>)
和 T putInstance(Class<T>, T)
。这个 Map 的最大优势在于,可以通过这两个方法执行类型安全的操作,彻底避免强制类型转换的麻烦。
在本教程中,我们将展示如何使用 Google Guava 的 ClassToInstanceMap
接口及其实现类。
2. Google Guava 的 ClassToInstanceMap
先看看如何使用这个工具类。首先在 pom.xml
中添加 Guava 库依赖:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
最新版本可查看 这里
ClassToInstanceMap
接口有两种实现:可变版本和不可变版本。我们分别来看。
3. 创建不可变实例 ImmutableClassToInstanceMap
创建 ImmutableClassToInstanceMap
实例有几种方式:
✅ 使用 of()
创建空 Map:
ImmutableClassToInstanceMap.of()
✅ 使用 of(Class<T> type, T value)
创建单元素 Map:
ImmutableClassToInstanceMap.of(Save.class, new Save());
✅ 使用 copyOf()
复制已有 Map:
ImmutableClassToInstanceMap.copyOf(someMap)
✅ 使用 Builder 模式(推荐多元素场景):
ImmutableClassToInstanceMap.<Action>builder()
.put(Save.class, new Save())
.put(Open.class, new Open())
.put(Delete.class, new Delete())
.build();
⚠️ 注意:不可变 Map 创建后不能修改,任何修改操作都会抛出 UnsupportedOperationException
。
4. 创建可变实例 MutableClassToInstanceMap
创建 MutableClassToInstanceMap
实例的方式更简单粗暴:
✅ 使用 create()
创建基于 HashMap 的实例:
MutableClassToInstanceMap.create();
✅ 使用 create(Map<Class<? extends B>, B> backingMap)
指定底层 Map:
MutableClassToInstanceMap.create(new HashMap());
踩坑提示:如果传入的 Map 非空,Guava 会直接使用它作为底层存储,可能导致初始数据不符合类型约束!
5. 核心方法使用
ClassToInstanceMap
在标准 Map
接口基础上增加了两个类型安全的方法:
5.1 类型安全的获取:<T extends B> T getInstance(Class<T> type)
对比传统方式:
// ❌ 传统方式需要强制转换
Action openAction = (Action) map.get(Open.class);
// ✅ 类型安全方式
Delete deleteAction = map.getInstance(Delete.class);
5.2 类型安全的存入:<T extends B> T putInstance(Class<T> type, @Nullable T value)
对比传统方式:
// ❌ 传统方式无类型检查
Action newOpen = (Action) map.put(Open.class, new Open());
// ✅ 类型安全方式
Delete newDelete = map.putInstance(Delete.class, new Delete());
核心优势:编译时就能发现类型错误,彻底避免运行时的
ClassCastException
!
6. 总结
ClassToInstanceMap
是 Guava 提供的一个实用工具,特别适合需要按类类型管理实例的场景。它的核心价值在于:
- ✅ 类型安全:通过泛型约束避免强制转换
- ✅ API 简洁:
getInstance/putInstance
方法语义清晰 - ✅ 实现灵活:提供可变/不可变两种实现
实际应用场景包括:
- 依赖注入容器
- 策略模式实现
- 插件系统架构
完整示例代码可在 GitHub 项目 中查看。