当前位置: 首页 > 面试题库 >

Gson ClassCastException(LinkedTreeMap)

慕宏博
2023-03-14
问题内容

使用Gson来反序列化参数化类的对象会Container<T>导致的java.lang.ClassCastException某些值T,例如对于RecordStringList<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()方法更改为非静态不能解决问题。

有任何想法吗?


问题答案:

您想要我的解决方案是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不知道我的种类并生成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);
    }
}


 类似资料:
  • 问题内容: 我知道以前曾问过这个问题。由于我的Java和android新手技能。我不能解决这个问题超过一个星期。 我和我的一个朋友开发了一个android项目,那里有几件事。 这件事中最奇怪的部分是,它仅在我从Google Play商店下载并对其进行测试时才发生。不是从本地android studio安装或调试模式。 这可能是什么问题,或者此返回列表完全错误?我的朋友说服此代码可以正确返回,但是从

  • 问题内容: 最近,我开始研究字符串,并被告知Google自己的库,是处理这些字符串的新方法。 据我了解,字符串本质上是一个映射。每个变量指向字符串中的值的位置。 例如: 到目前为止,一切都很好。可以使用以下代码将诸如创建此字符串的时间之类的信息分配给变量: 简单的美感几乎具有艺术性。但这就是美的终结,我的困惑开始了。 以下是上述字符串的扩展; 我的问题是这些“括号内的括号”如何用于“ ?” 部分?

  • 最奇怪的是,只有当我从Google play商店下载并测试它时,它才会发生。不是从本地android studio安装或调试模式。 这里的问题是什么,或者这个返回列表是完全错误的?我的朋友确信,这段代码返回正确,但从play store安装,它总是一个错误。 请建议我在哪里继续挖掘? 例外是 java.lang.ClassCastException:com.google.gson.internal

相关阅读

相关文章

相关问答