Gson与泛型Map

8cdiaqws  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(121)

我试图访问与此相关的每个SO线程,但我没有成功地了解我的问题的来源,
我正在使用〈String,Objects〉的Map,如下所示,我使用了Gson ReadMe中显示的TypeToken来捕获运行时的类型,我准备了两个测试方法来演示我的问题,我认为两个测试具有相同的语义,但不会产生相同的结果,
test2将生成一些LinkedTreeMap并导致NPE,而test1将成功

// my Model

public static class DataType implements Distinguishable, Serializable {
        private final String id;
        private final int i;
        public DataType(String id, int i){
            this.id = id;
            this.i = i;
        }
        @Override
        public String getID() {
            return id;
        }

        public String getId() {
            return id;
        }

        public int getI() {
            return i;
        }
    }

// test 1:

@Test
    public void shouldSerAndDesAMap(){

        // manual
        Type type = new TypeToken<Map<String,DataType>>(){}.getType();

        Map<String,DataType> map = new HashMap<String,DataType>(){{
            put("s1",new DataType("s1",1));
            put("s2",new DataType("s2",2));
        }};

        String s = g.toJson(map,type);
        Map<String,DataType> m = g.fromJson(s,type);

        System.out.println(m.get("s1").getI());
    }

// test 2 (and its utils):

    Gson g = new GsonBuilder().setPrettyPrinting().create();

    private <T extends Distinguishable> String serialize(Map<String,T> map){
        Type type = new TypeToken<Map<String,T>>(){}.getType(); // generating TypeToken 
        return g.toJson(map,type);
    }

    private <T extends  Distinguishable> Map<String,T> deserialize(String s){
        Type type = new TypeToken<Map<String,T>>(){}.getType();
        return g.fromJson(s,type);
    }

    @Test
    public void shouldSerAndDesByGenerics(){
        Map<String,DataType> map = new HashMap<String,DataType>(){{
            put("s1",new DataType("s1",1));
            put("s2",new DataType("s2",2));
        }};

        String s = serialize(map);
        System.out.println(s);
        Map<String,DataType> m = deserialize(s);

        System.out.println(m.get("s1").getI());
    }

如果我仍然面临Java type Erasure,我如何克服这个问题?我需要生成一个泛型类,将TypeToken作为其字段,而我不能要求用户将其注入,

cigdeys3

cigdeys31#

一个朋友给我指了this

private <T extends Distinguishable> String serialize(Map<String,T> map, Class<T> clazz){
        Type type = TypeToken.getParametrized(Map.class,String.class,clazz) // generating TypeToken 
        return g.toJson(map,type);
    }

这样我就能达到我的目的,

相关问题