我试图访问与此相关的每个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);
}
这样我就能得到我想要的,