【问题标题】:How do I deserialize an object with a generic type?如何反序列化具有泛型类型的对象?
【发布时间】:2014-08-14 04:10:23
【问题描述】:
public class ResponseData<T>
{
    @SerializedName("status")
    private String mStatus;
    @SerializedName("description")
    private String mDescription;
    @SerializedName("data")
    private ArrayList<T> mData;
    @SerializedName("error_code")
    private int mErrorCode;

    public String getStatus() {return mStatus;}
    public String getDescription() { return mDescription;}
    public ArrayList<T> getData() { return mData; }
}

//常用字段放这里

public class BaseData {}

//用户字段到这里

public class UserData extends BaseData {}

//一些位置字段放在这里

public class LocationData extends BaseData {}

//Json反序列化器

public class JsonDeserializer
{
    public static String toJson(Object t)
    {
        return new Gson().toJson(t);
    }

    public static <T> T fromInputStream(InputStream inputStream, Class<T> clz)
    {
        Reader reader = new InputStreamReader(inputStream);
        return new Gson().fromJson(reader, clz);
    }
}


public class HttpRequester
{
    public enum RequestType {GET, POST, DELETE, PUT};

    public void makeRequest(RequestType requestType, BaseData baseData, String path)
    {

        //submit data to api
        //the api then returns a response
        // baseData.getClass(); //this can either be UserData or LocationData

        HttpEntity entity = response.getEntity();

        //I am getting stuck here. I want the responseData mData field to be the same type as the baseData I am sending to the api.

        //this is not valid syntax
        ResponseData response = JsonDeserializer.fromInputStream(entity.getContent(), ResponseData<baseData.getClass()>.class );

    }
}

这里是一些示例 json

{"data":[{"username":"james","email":"james@gmail.com","height":72.0,"phone":"+15555555555"}], "error_code": 0, "description":null }

{"data":[{"latidue":40.022022,"longitude":-29.23939, "street":"union ave", "borough":"manhattan"}', "error_code": 0, "description":null }

JsonDeserializer 应该返回 ResponseData,mData 是 LocationData 类型的数组列表,或者 ResponseData,mData 是 UserData 类型的数组列表。

【问题讨论】:

    标签: java json generics gson json-deserialization


    【解决方案1】:

    首先,don't use raw types.

    其次,您需要使用类型标记。 TypeToken 是一种伪黑客,可以绕过类型擦除的一些限制。

    您需要创建一个类型标记

    TypeToken token = new TypeToken<ResponseDate<LocationData>>() {};
    

    然后将TypeToken的表示类型提供给Gson(不要每次都重新创建一个新的Gson对象,保存并使用一个实例)

    gson.fromGson(reader, token.getType());
    

    对于ResponseData&lt;..&gt; 的每个参数化版本,您需要有一个TypeToken

    相关:

    【讨论】:

    • 感谢您为我指明了正确的方向。我知道我必须使用 TypeToken 唯一的问题是我试图弄清楚如何在运行时获取类型令牌。我能够通过使用工厂模式来解决。 ResponseData 可以是位置数据或用户数据。所以我创建了一个令牌工厂,它返回一个新的 TypeToken>() {};或新的 TypeToken>() {};并将其传递给 JsonDeserializer.fromInputStream
    猜你喜欢
    • 2020-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多