你可以很好地存储元素的类型,将你期望的类型传递给get()方法并检查那里。 AFAIK没有内置的方法来存储不同类型的类型安全而没有一些常见的超类或接口。
基本上你这样做:
private static final Map lookup = new HashMap<>();
private static final Map> types= new HashMap<>();
public static T get(CacheHelper key, Class expectedType ) {
Class> type = types.get(key.getId());
if( type == null || expectedType == null || expectedType.isAssignableFrom( type ) ) {
throw new IllegalArgumentException("wrong type");
}
return (T)lookup.get(key.getId());
}
//if null values should be allowed, you'd need to change the signature to use generics
//and pass the expected type as well, e.g. void store(CacheHelper key, T value, Class type)
public static void store(CacheHelper key, Object value ) {
lookup.put(key.getId(), value);
types.put( key.getId(), value.getClass() );
}
请注意,由于您基本上禁用了缓存中的泛型,因此仍然无法捕获任何编译时错误。 如果没有常见的超类/接口或缓存本身的泛型类型,那么就没有编译时间来捕获这些错误 - 至少不容易。
如果你只是不想自己进行强制转换,你可以将它们隐藏在get()并使用可能的类强制转换异常。 在这种情况下,您可以让编译器从调用中推断出T的类型(通过赋值,显式设置或参数类型)。
但是,传递期望的类很容易提供额外的信息,您可以使用它们来创建更好的错误消息等,这些消息是您从ClassCastException获得的。