使用Google-gson进行JSON序列化/反序列化通用类型

5

我必须承认我不擅长Java中的泛型。

我使用JavaScriptSerializer在C#中编写了一个JSON序列化/反序列化类。

    private static JavaScriptSerializer js = new JavaScriptSerializer();

    public static T LoadFromJSONString<T>(string strRequest)
    {
        return js.Deserialize<T>(strRequest);
    }

    public static string DumpToJSONString<T>(T rq)
    {
        return js.Serialize(rq);
    }

它在C#中运行良好。现在我正在尝试将其转换或者至少在Java中编写另一个JSON序列化/反序列化类。我已经尝试了flexjsongoogle-gson,但是我不知道如何在Java中指定<T>。

有人可以帮助我吗?顺便说一下,我更喜欢google-gson

3个回答

9
在Java中,你必须传递实际的类型擦除类,而不仅仅是类型参数,这样数据绑定程序才知道要使用哪种类型;因此类似以下代码:
public static T LoadFromJSONString<T>(string strRequest, Class<T> type)
{
    Gson gson = new Gson();
    return gson.fromJson(strRequest, type);
}

但是这通常只需要用于反序列化;在序列化时,您拥有一个类库可以使用的实例。

顺便说一下,你可能想考虑使用另一个很好的Java JSON库Jackson; 但是,对于这个特定的示例,你提到的所有库都可以工作。


嗯,但是假设我只有类信息的字符串,例如String clazz = "com.example.Response",那么我该如何使用这段代码呢? - Tuan Anh Hoang-Vu
2
你可以使用 Class.forName("com.example.Response") 来找到它。 - StaxMan
是的,我已经尝试过了。但问题在于,当我使用Class.forName()时,返回类型必须是Object而不是Response,我必须明确地声明如下:Response rp = (Response) LoadFromJSONString(resString, Class.forName("com.example.Response")) - Tuan Anh Hoang-Vu
由于Class.forName()返回一个Class <?>,因此您需要进行一些转换; 尽管很丑陋,但这并不会阻止它工作。 接口通常需要类型参数,以便类的显式传递(Response.class是类型为Class <Response>的)与类型参数兼容; 但这更像是一个好功能而已。 因此,您必须传递要绑定的类; 类型参数T对于Java来说不足以确定实际的真实类型。 - StaxMan

1

经过深思熟虑,我认为没有一种方法可以像您的C#代码那样优雅地解决这个问题。这是由于Java编译器执行的类型擦除。

对于您来说,最好的解决方案可能是在您知道需要序列化/反序列化对象类型的位置使用Gson对象。

如果您不想每次都创建Gson对象实例,当然可以将其保持静态,因为创建时不需要任何类型参数。


-1

这应该可以工作:

import com.google.gson.Gson;
public class GenericClass {

    private static Gson gson = new Gson(); 

    public static <T> T loadFromJSONString(String strRequest)
    {
        return (T) gson.fromJson(strRequest, T.class);
    }

    public static <T> String dumpToJSONString(T rq)
    {
        return gson.toJson(rq);
    }
}

嗯,等等。那样行不通。这一行会引起问题: return (T) gson.fromJson(strRequest, T.class); - Fredrik Wallenius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接