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);
在這個特定的(故意過度簡化的)示例中,這看起來可以以更簡單、更優雅的方式完成,但當它是更大、更復雜場景的一部分時,它可能是唯一的選擇。
添加回答
舉報