如何解决由Java泛型引起的ClassCastException

时间:2019-01-18 02:47:49

标签: java

大多数人都遇到了由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 ++这样的真正泛型?

1 个答案:

答案 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);
        }
    }