这是一些无法编译的代码。我想在typeMap中保留Class<?>
(键)和Map<Long, ObjectDescriptors<?>>
(值)的任意对;
从其他方法我想使用具有具体类型的值映射之一,但算法应该是通用的。我编写了getIdentityMap()
方法来提供具有通用类型的地图。
如何在通用时修改要编译的代码?
提前致谢。
private final Map<Class<?>, Map<Long, ObjectDescriptor<?>>> typeMap = new HashMap<Class<?>, Map<Long,ObjectDescriptor<?>>();
private <T> Map<Long, ObjectDescriptor<T>> getIdentityMap(Class<T> type) {
Map<Long, ObjectDescriptor<T>> identityMap = typeMap.get(type);
if (identityMap == null) {
identityMap = new HashMap<Long, ObjectDescriptor<T>>();
typeMap.put(type, identityMap);
}
return identityMap;
}
编辑:以下是编译器错误:
Map<Long, ObjectDescriptor<OBJECT_TYPE>> identityMap = typeMap.get(type);
Type mismatch: cannot convert from Map<Long,ObjectDescriptor<Object>> to Map<Long,ObjectDescriptor<OBJECT_TYPE>>
typeMap.put(type, identityMap);
The method put(Class<?>, Map<Long,ObjectDescriptor<Object>>) in the type Map<Class<?>,Map<Long,ObjectDescriptor<Object>>> is not applicable for the arguments (Class<OBJECT_TYPE>, Map<Long,ObjectDescriptor<OBJECT_TYPE>>)
编辑:将地图属性的通用类型编辑为?
答案 0 :(得分:1)
您无法使用“T”创建通用实例。尝试使用“?”
private final Map<Class<?>, Map<Long, ObjectDescriptor<?>>> typeMap = new HashMap<Class<?>, Map<Long,ObjectDescriptor<?>>>();
private <T> Map<Long, ObjectDescriptor<?>> getIdentityMap(Class<?> type) {
Map<Long, ObjectDescriptor<?>> identityMap = typeMap.get(type);
if (identityMap == null) {
identityMap = new HashMap<Long, ObjectDescriptor<?>>();
typeMap.put(type, identityMap);
}
return identityMap;
}
正如评论中所提到的,这是因为Java擦除以保持与不使用泛型的旧类的兼容性。编译器从参数和参数中删除类型信息。
答案 1 :(得分:1)
如果您愿意重新设计一下并且可以使用单个未经检查的演员(IMO绝对不会失败),您可以这样做。
public class TmpTest {
public static void main(final String[] args) {
ClassDescriptorMap m = new ClassDescriptorMap();
LongDescriptorMap<String> identityMap = m.getIdentityMap(String.class);
identityMap.put(1L, Arrays.asList("hi"));
System.out.println(identityMap);
identityMap = m.getIdentityMap(String.class);
identityMap.put(2L, Arrays.asList("hello"));
System.out.println(identityMap);
LongDescriptorMap<Object> identityMap2 = m.getIdentityMap(Object.class);
System.out.println(identityMap2);
}
}
class ClassDescriptorMap {
private final Map<Class<?>, LongDescriptorMap<?>> typeMap = new HashMap<Class<?>, LongDescriptorMap<?>>();
public <T> LongDescriptorMap<T> getIdentityMap(Class<T> type) {
@SuppressWarnings("unchecked")
LongDescriptorMap<T> identityMap = LongDescriptorMap.class.cast(typeMap.get(type));
if (identityMap == null) {
identityMap = new LongDescriptorMap<T>();
typeMap.put(type, identityMap);
}
return identityMap;
}
@Override
public String toString() {
return typeMap.toString();
}
}
class LongDescriptorMap<T> {
private Map<Long, List<T>> map = new HashMap<Long, List<T>>();
public List<T> get(Object key) {
return map.get(key);
}
public List<T> put(Long key, List<T> value) {
return map.put(key, value);
}
@Override
public String toString() {
return map.toString();
}
}