引起:java.lang.ClassCastException:使用Generic Type时,libcore.reflect.ParameterizedTypeImpl无法强制转换为java.lang.Class

时间:2016-01-26 07:30:41

标签: java android generics exception casting

我创建了一个类扩展AsyncTask来解析Json使用Gson,因为输入可以是很多类型的我使用泛型类型:

public class ApiResponse<T> extends AsyncTask...

我需要知道T类的类型才能传递Gson:

(1)

Class<T> clazz =
    (Class<T>)((ParameterizedType)
        getClass().getGenericSuperclass())
    .getActualTypeArguments()[0];

new Gson().fromJson(reader, clazz);

但是,这里的T可以是一个有很多类型的类,所以有时我会通过类:

(2)

public class DataMessage<T> implements Serializable{...}

由于这些类具有此格式,因此我收到了由以下原因引起的异常:

java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class

at(1)

在这种情况下我该怎么做?

更新:

public class DataMessage<T> implements Serializable{

    @SerializedName("pagination")
    private Pagination pagination;
    @SerializedName("meta")
    private Message meta;
    @SerializedName("data")
    private T data;

    public DataMessage(T data) {
        this.data = data;
    }

    public Pagination getPagination() {
        return pagination;
    }

    public void setPagination(Pagination pagination) {
        this.pagination = pagination;
    }

    public Message getMeta() {
        return meta;
    }

    public void setMeta(Message meta) {
        this.meta = meta;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public class Pagination {
        @SerializedName("next_max_tag_id")
        public String nextMaxTagId;
        @SerializedName("deprecation_warning")
        public String deprecationWarning;
        @SerializedName("next_max_id")
        public String nextMaxId;
        @SerializedName("next_min_id")
        public String nextMinId;
        @SerializedName("min_tag_id")
        public String minTagId;
        @SerializedName("next_url")
        public String nextUrl;
    }

    public class Message {
        @SerializedName("error_type")
        public String errorType;
        @SerializedName("code")
        public int code;
        @SerializedName("error_message")
        public String error_message;
    }
}

3 个答案:

答案 0 :(得分:2)

当我需要使用Gson解析特定类的JSON时,我以这种方式使用 GsonBuilder

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
   public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        try{
           return new Date( json.getAsJsonPrimitive().getAsLong()*1000L );
        }catch( Exception e ){
            return null;
        }

   }
});

Gson gson = gsonBuilder.create();

在你的情况下,我认为你可以用这种方式解析你的JSON:

DataMessage<YourClass> dataMessage = gson.fromJson(yourJsonObj, DataMessage.class);

另一件事是你可以用这种方式获得确切的类型

Type collectionType = new TypeToken<DataMessage<T>>() {}.getType();

但是当你反序列化时,你可能会得到一个糟糕的Json ......

最好的方法是使用类而不是T,这样Gson就知道什么必须序列化/反序列化

Type collectionType = new TypeToken<DataMessage<YourClass>>() {}.getType();

我找到了你Deserializing Generic Types with GSON

答案 1 :(得分:0)

假设您要反序列出PFObject *order = [PFObject objectWithClassName:@"Order"]; order[@"totalPrice"] = @1337; order[@"P_ID"] = theProduct.objectId; [order saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { if (succeeded) { // The object has been saved. } else { // There was a problem, check error.description } }]; using a JsonReader的列表。

DataMessage<T>

然后你有

public <T> T Gson::fromJson(JsonReader reader, Type typeOfT)

答案 2 :(得分:0)

感谢@Andrea Catania提供的有用帮助,

问题在于,当我将((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];转换为Class类型时,使用DataMessage<T>类型无法转换。

但是((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]类型为类型,因此我不需要将其强制转换为,我将clazz变量重新键入键入(不是),问题已解决。