大多数人都遇到了由Java泛型引起的ClassCastException。大家都知道这是因为Java通用擦除,但是我们应该如何解决这个问题呢?例如:
Map<Integer,Long> map = new HashMap<>();
map.put(1,0L);
// I know this way violates the java generic constraint.
String json = JSONUtils.toJSONString(map);
Map<Integer,Long> mapFromJson = JSONUtils.parseMap(json);
for(Long v : mapFromJson.values()){
// will throw ClassCastException
System.out.println(v);
}
java泛型约束太多,因此在使用它时必须小心。为什么Java不使用像C ++这样的真正泛型?
答案 0 :(得分:1)
本来应该有Java泛型擦除,但是我们知道泛型是什么,因此我们可以用杰克逊解决它。
@Test
void 测试() {
Map<Integer,Long> map = new HashMap<>();
map.put(1,0L);
String json = null;
try {
json = mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
MapType mapType = mapper.getTypeFactory().constructMapType(map.getClass(), Integer.class, Long.class);
Map<Integer,Long> mapFromJson = null;
try {
mapFromJson = mapper.readValue(json,mapType);
} catch (IOException e) {
e.printStackTrace();
}
for(Long v : mapFromJson.values()) {
// will not throw ClassCastException
System.out.println(v);
}
}
也许是更好的方法,因为您可以复制类型:
@Test
void 测试() {
Map<Integer,Long> map = new HashMap<>();
map.put(1,0L);
// I know this way violates the java generic constraint.
String json = null;
try {
json = mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
Map<Integer,Long> mapFromJson = null;
try {
mapFromJson = mapper.readValue(json, new TypeReference<Map<Integer,Long>>(){});
} catch (IOException e) {
e.printStackTrace();
}
for(Long v : mapFromJson.values()) {
// will throw ClassCastException
System.out.println(v);
}
}