侧边栏壁纸
博主头像
colo

欲买桂花同载酒

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

设计一个通用的类型安全缓存类

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

题目

设计一个通用的类型安全缓存类

信息

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

考点

泛型类定义,类型擦除,泛型边界,类型安全

快速回答

实现要点:

  • 使用泛型类 GenericCache<T> 确保类型安全
  • 通过 Map<String, T> 存储数据
  • 添加 <T extends Cacheable> 边界限制
  • 实现 put/get 方法并处理空值
  • 注意类型擦除对运行时类型检查的影响
## 解析

问题背景

在实际开发中,经常需要实现缓存功能。使用泛型可以创建类型安全的缓存类,避免强制类型转换错误,同时保证代码复用性。

解决方案

// 定义缓存对象接口
interface Cacheable {
    String getId();
}

// 泛型缓存类实现
public class GenericCache<T extends Cacheable> {
    private final Map<String, T> cache = new HashMap<>();

    public void put(T item) {
        if (item == null) throw new IllegalArgumentException("Item cannot be null");
        cache.put(item.getId(), item);
    }

    public T get(String id) {
        return cache.get(id);
    }

    public void remove(String id) {
        cache.remove(id);
    }
}

// 使用示例
class User implements Cacheable {
    private String id;
    private String name;

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String getId() { return id; }
}

public class Main {
    public static void main(String[] args) {
        GenericCache<User> userCache = new GenericCache<>();
        userCache.put(new User("U1", "Alice"));

        // 类型安全获取(无需强制转换)
        User user = userCache.get("U1");

        // 错误示例(编译时报错)
        // Integer num = userCache.get("U1"); 
    }
}

核心原理

  • 类型安全:泛型在编译时检查类型一致性,避免 ClassCastException
  • 类型擦除:运行时泛型类型信息被擦除,GenericCache<User>GenericCache<Product> 的 Class 对象相同
  • 边界限制<T extends Cacheable> 确保只有实现指定接口的类型可用

最佳实践

  • 始终使用泛型类型参数声明变量(如 Map<String, T>
  • 对可能为 null 的返回值进行显式处理
  • 在泛型类中避免使用原始类型(Raw Types)
  • 优先使用接口(如 Cacheable)定义边界

常见错误

  • 忽略空值检查cache.get("invalid") 返回 null 可能导致 NPE
  • 错误处理类型擦除:尝试在运行时获取泛型类型(如 if(data instanceof T)
  • 不当使用原始类型GenericCache rawCache = new GenericCache(); 会绕过类型检查

扩展知识

  • 通配符:使用 GenericCache<? extends Cacheable> 增加灵活性
  • 类型令牌:通过 Class<T> 参数保留类型信息(如 class GenericCache<T> { private Class<T> type; }
  • 泛型方法:在静态方法中使用独立泛型参数(如 <U> void mergeCache(GenericCache<U> other)