3 回答
TA贡献1851条经验 获得超5个赞
有一些类型使用提示:
<T>由于泛型类型被擦除,在不传递实际类型的情况下使用是一个骗局。传递类型 as
Class<T>不是一个好主意,因为###.class它仅代表 JVM 加载的类(原始类型除外)。有了它,Class<List<String>>并且Class<List<Map<Integer, ?>>>完全一样的List.class丢失类型参数化,因此使 Gson(反)序列化工作时没有考虑到正确的类型(例如,如果我记得的话,LinkedHashTreeMap 就是一个很好的例子)。Gson 主要使用
Type它是可以由 Java 类型系统表示的任何类型(包括类ParameterizedType、等)的超类型接口。见https://google.github.io/gson/apidocs/com/google/gson/Gson.html#fromJson-java.lang.String-java.lang.reflect.Type-TypeToken是 Java 中泛型类型持有者的一个很好的例子,包括它根据构建方式生成正确的类型信息。它可用于使您的方法类型安全:public static <T> T fromJson(String doc, TypeToken<? extends T> typeToken) { return sGson.fromJson(doc, typeToken.getType()); }. 类型标记可以缓存到公共的(是的)静态最终字段中,因为它是不可变的并且跨线程是线程安全的。
奖金:
不需要
synchronized:Gson实例也是线程安全的。
TA贡献1795条经验 获得超7个赞
如果可能的话,Gson可能已经添加了这个方法,它可能看起来像这样:
TestDocument document = gson.<TestDocument>fromJson(json);
具有此签名的方法:
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException
包括JavaDoc:
该方法将指定的 Json 反序列化为指定类的对象。如果指定的类是泛型类型,则不适合使用,因为Java 的类型擦除特性,它不会具有泛型类型信息。因此,如果所需的类型是泛型类型,则不应使用此方法。请注意,如果指定对象的任何字段都是泛型,则此方法可以正常工作,只是对象本身不应该是泛型类型。对于对象是泛型类型的情况,调用
fromJson(String, Type)。如果您在 aReader而不是 a中有 JsonString,请fromJson(Reader, Class)改用。
甚至第二个参数名称也是classOfT有意义the class of T的。
TA贡献1844条经验 获得超8个赞
看起来如果不显式传递实际类型以便在构建时知道它,就不可能在 Java 中执行此操作。
这是一个解决方案:
public static synchronized <T> T fromJson(String doc, Class<T> type) {
return sGson.fromJson(doc, type);
}然后测试通过:
assertEquals((new TestDocument("test").test), Utils.<TestDocument>fromJson("{\"test\": \"test\"}", TestDocument.class).test);在这个特定的(故意过度简化的)示例中,这看起来可以以更简单、更优雅的方式完成,但当它是更大、更复杂场景的一部分时,它可能是唯一的选择。
添加回答
举报
