侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

设计一个类型安全的异构容器

2025-12-11 / 0 评论 / 4 阅读

题目

设计一个类型安全的异构容器

信息

  • 类型:问答
  • 难度:⭐⭐

考点

泛型应用,类型安全,类型令牌

快速回答

通过泛型实现一个可存储多种类型对象的容器:

  • 使用Class<T>作为键保证类型安全
  • 通过put方法存储对象时绑定类型信息
  • 通过get方法获取对象时进行动态类型检查
  • 利用Class.cast()实现安全的类型转换
## 解析

问题背景

常规容器(如Map<K, V>)只能存储单一类型元素。实际场景中可能需要存储多种类型对象(如配置中心需存储String、Integer等不同类型配置值),同时保证类型安全。

解决方案

public class TypeSafeContainer {
    private Map<Class<?>, Object> container = new HashMap<>();

    public <T> void put(Class<T> type, T instance) {
        container.put(Objects.requireNonNull(type), instance);
    }

    public <T> T get(Class<T> type) {
        return type.cast(container.get(type));
    }
}

核心原理

  • 类型令牌(Type Token):利用Class<T>对象携带泛型类型信息
  • 类型安全put方法通过泛型参数约束键值类型一致性
  • 动态转换get方法使用Class.cast()实现运行时类型检查

使用示例

TypeSafeContainer container = new TypeSafeContainer();
container.put(String.class, "Config Value");
container.put(Integer.class, 42);

String s = container.get(String.class);  // 正确
Integer i = container.get(Integer.class); // 正确
Double d = container.get(Double.class);   // 返回null
String error = container.get(Integer.class); // ClassCastException

最佳实践

  • 优先使用Class.cast()而非强制转换,提供更好的类型安全
  • null值做防御性处理(如示例中的Objects.requireNonNull
  • 考虑线程安全场景可使用ConcurrentHashMap

常见错误

  • 原始类型问题container.put(int.class, 1)会导致自动装箱,实际存储
  • 子类类型问题container.put(Number.class, 1)get(Integer.class)返回null
  • 通配符误用:错误使用Class<?>作为键会破坏类型安全

扩展知识

  • Super Type Token:解决泛型类型擦除问题(如存储List<String>
    TypeReference<List<String>> token = new TypeReference<>(){};
    // 通过token.getType()获取完整泛型类型
  • 类型安全限制:无法用于重载方法(类型擦除后方法签名相同)
  • Java 8+优化:使用computeIfAbsent实现延迟初始化