java - 如何将泛型类型存储在缓存中以避免在检索时进行未经检查的强制转换?

标签 java generics caching

必须删除其中的一些细节,但基本上我试图缓存返回对象集合的昂贵操作的结果,但这些单独对象的类型在编译时是未知的(仅一个基类)。

public class SomeClass
{
    private static final Map<Integer,Collection<? extends SomeBaseClass>> theCache = new HashMap<Integer,Collection<? extends SomeBaseClass>>();

    public <T extends SomeBaseClass> Collection<T> theMethod(Class<T> theClass, int index)
    {
        if (theCache.containsKey(index))
        {
            return (Collection<T>) theCache.get(index);
        }
        else
        {
            Collection<T> result = someExpensiveOperation(theClass, index);
            theCache.put(index, result);
            return result;
        }
    }

    // ...

}

这里的缓存检索是一个未经检查的转换,因为代码只是相信调用者传递给方法的类参数与先前创建对象的调用传递的类参数兼容(应该相同)首先在缓存中。

是否有某种方式或设计模式将实际类与对象本身一起缓存,从而避免这种未经检查的转换?

最佳答案

没有直接支持这种行为。

如果缓存包含单个元素,可以使用Class.cast(),它会在不匹配的情况下抛出一个ClassCastException:

private Map<Integer, ?> cache = ...;

public <T> T get(Integer id, Class<T> c) {
    return c.cast(cache.get(id));
}

在缓存集合的情况下,它会更复杂。如果您真的想避免未经检查的转换,您可以创建一个新集合并通过 Class.cast() 填充它:

Collection<T> result = ...;
for (Object o: theCache.get(index)) 
    result.add(theClass.cast(o));
return result;

其他方法包括,例如,使用 Guava 的 Collections2.transform() 创建一个“已检查”的 Collection View :

public class Cast<T> implements Function<Object, T> {
    private Class<T> type;
    public Cast(Class<T> type) {
        this.type = type;
    }

    public T apply(Object in) {
        return type.cast(in);
    }
}

.

return Collections2.transform(theCache.get(index), new Cast<T>(theClass));

关于java - 如何将泛型类型存储在缓存中以避免在检索时进行未经检查的强制转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4238868/

相关文章:

php - Twig 输出缓存

java - 使用 Hibernate 的 Java Web 服务中的内存泄漏

c# - 一种在开放委托(delegate)和封闭委托(delegate)之间执行转换的方法

java - 对类加载时未知的常量使用 final 和 static

typescript - 描述 TypeScript 中输入类型的联合

java - 混合泛型方法和 Java 8 语法的复合表达式无法编译

android - 客户经理缓存 Android

.net - 如何同步 Redis 与本地内存缓存?

java - 为什么在销毁有状态 EJB 时使实例变量无效?

Java Map 合并与 computeIfAbsent 和 computeIfPresent