如何使用泛型类型反序列化对象?

时间:2014-06-24 02:28:59

标签: java json generics gson json-deserialization

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 Deserializer

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的arraylist,或者是ResponseData,其中mData是一个类型为UserData的arrayList。

1 个答案:

答案 0 :(得分:1)

首先,don't use raw types.

其次,您需要使用类型令牌。 TypeToken是一种伪破解,可以解决类型擦除的一些限制。

您需要创建一个类型令牌

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

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

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

对于TypeToken的每个参数化版本,您需要ResponseData<..>

相关: