Gson and Map of Generics



我试图访问与此相关的每个SO线程,但我没有成功理解我的问题的来源,

我正在使用<String,Objects>如下所示,我在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作为它的字段,而我不能要求用户注入它,

一个朋友指给我看的

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

这样我就能得到我想要的,

最新更新