Gson ClassCastException(LinkedTreeMap)

问题描述 投票:-1回答:1

使用Gson反序列化参数化类Container<T>的对象,得到java.lang.ClassCastException的某些T值,例如:对于由RecordString字段组成的简单List<String>类型:

com.google.gson.internal.LinkedTreeMap cannot be cast to Record

有趣的是,相同的代码在内联调用fromJson()方法时起作用,即以下语句确实返回有效值:

Container<Record> value = new Gson().fromJson(
  json, new TypeToken<Container<Record>>(){}.getType());

Container<T>的定义也很简单:

public class Container<T> {
  private static final Gson PARSER = new Gson();
  private String id;
  private List<T> content;
  private Object data;
  public static <T> Container<T> deserialize(String json, Class<T> type) {
    return PARSER.fromJson(json, new TypeToken<Container<T>>(){}.getType());
  }
}

deserialize()方法更改为非静态方法无法解决问题。

有任何想法吗?

java json gson classcastexception linkettreemap
1个回答
1
投票

你想要ParameterizedType我的解决方案是创建

    public static <T> Container<T> deserialize(String json, Class<T> clazz) {
        Type type = TypeToken.getParameterized(Container.class,clazz).getType();
        return new Gson().fromJson(json, type);
    }

问题是T,因为Java不知道我的类型并生成Type of T

    public static <T> Container<T> sec(String json, Class<T> clazz) {
        Type type1 = new TypeToken<Container<T>>() { }.getType();
        Type type = TypeToken.getParameterized(Container.class,clazz).getType();
        System.out.println(type1);   //==>pl.jac.container.Container<T>
        System.out.println(type);    //==>pl.jac.container.Container<pl.jac.container.Record>
        return new Gson().fromJson(json, type);
    }

这是测试更多示例来纠正运行测试testContainerRecord2是针对您的问题

import java.lang.reflect.Type;
import org.junit.Test;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import static org.junit.Assert.assertEquals;

public class ContainerTest {

    @Test
    public void testContainerRecord() {
        //given
        String json = "{\"id\":\"new ID\",\"content\":[{\"id\":\"50e0300a-6668-42b3-a474-81a6a08f773f\"},{\"id\":\"f0bee3f3-2c40-4b44-8608-a6fedb226b7a\"}],\"data\":\"AAAAAAAA\"}";
        //when

        Container<Record> containerRecord = Container.deserializeClass(json, ContainerRecord.class);
        //then
        assertEquals("50e0300a-6668-42b3-a474-81a6a08f773f", containerRecord.content.get(0).id);
        assertEquals("f0bee3f3-2c40-4b44-8608-a6fedb226b7a", containerRecord.content.get(1).id);
    }

    @Test
    public void testContainerRecord2() {
        //given
        String json = "{\"id\":\"new ID\",\"content\":[{\"id\":\"50e0300a-6668-42b3-a474-81a6a08f773f\"},{\"id\":\"f0bee3f3-2c40-4b44-8608-a6fedb226b7a\"}],\"data\":\"AAAAAAAA\"}";
        //when

        Container<Record> containerRecord = Container.deserialize(json, Record.class);
        //then
        assertEquals("50e0300a-6668-42b3-a474-81a6a08f773f", containerRecord.content.get(0).id);
        assertEquals("f0bee3f3-2c40-4b44-8608-a6fedb226b7a", containerRecord.content.get(1).id);
    }

    @Test
    public void testGenericWithType() {
        //given
        String json = "{\"id\":\"new ID\",\"content\":[{\"id\":\"50e0300a-6668-42b3-a474-81a6a08f773f\"},{\"id\":\"f0bee3f3-2c40-4b44-8608-a6fedb226b7a\"}],\"data\":\"AAAAAAAA\"}";
        //when
        Type type = new TypeToken<Container<Record>>() {
        }.getType();

        Container<Record> containerRecord = Container.deserializeType(json, type);
        //then
        assertEquals("50e0300a-6668-42b3-a474-81a6a08f773f", containerRecord.content.get(0).id);
        assertEquals("f0bee3f3-2c40-4b44-8608-a6fedb226b7a", containerRecord.content.get(1).id);
    }

    @Test
    public void testRecord() {
        //given
        String json = "{\"id\":\"new ID\",\"content\":[{\"id\":\"50e0300a-6668-42b3-a474-81a6a08f773f\"},{\"id\":\"f0bee3f3-2c40-4b44-8608-a6fedb226b7a\"}],\"data\":\"AAAAAAAA\"}";
        //when
        ContainerRecord containerRecord = new Gson().fromJson(json, ContainerRecord.class);
        //then
        assertEquals("50e0300a-6668-42b3-a474-81a6a08f773f", containerRecord.content.get(0).id);
        assertEquals("f0bee3f3-2c40-4b44-8608-a6fedb226b7a", containerRecord.content.get(1).id);
    }

    @Test
    public void testRecordWithType() {
        //given
        String json = "{\"id\":\"new ID\",\"content\":[{\"id\":\"50e0300a-6668-42b3-a474-81a6a08f773f\"},{\"id\":\"f0bee3f3-2c40-4b44-8608-a6fedb226b7a\"}],\"data\":\"AAAAAAAA\"}";
        //when
        Type type = new TypeToken<Container<Record>>() {
        }.getType();
        Container<Record> containerRecord = new Gson().fromJson(json, type);
        //then
        assertEquals("50e0300a-6668-42b3-a474-81a6a08f773f", containerRecord.content.get(0).id);
        assertEquals("f0bee3f3-2c40-4b44-8608-a6fedb226b7a", containerRecord.content.get(1).id);
    }

    @Test
    public void testContainerString() {
        //given
        String json = "{\"id\":\"new ID\",\"content\":[\"37c84304-ab80-4f92-8b2a-710b362ecb3f\"],\"data\":\"AAAAAAAA\"}";
        //when
        Type type = new TypeToken<Container<String>>() {
        }.getType();
        Container<String> containerRecord = new Gson().fromJson(json, type);
        //then
        assertEquals("37c84304-ab80-4f92-8b2a-710b362ecb3f", containerRecord.content.get(0));
    }


}

我的班级记录

public class Record {
    public String id;
}

和我的容器

public class ContainerRecord extends Container<Record> {
}

和容器

public class Container<T> {

    public String id;
    public List<T> content;
    public Object data;

    public static <T> Container<T> deserializeClass(String json, Class<? extends Container<T>> type) {
        return new Gson().fromJson(json, type);
    }
    public static <T> Container<T> deserializeType(String json, Type type) {
        return new Gson().fromJson(json, type);
    }

    public static <T> Container<T> deserialize(String json, Class<T> clazz) {
        Type type = TypeToken.getParameterized(Container.class,clazz).getType();
        return new Gson().fromJson(json, type);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.