【问题标题】:Deserialize a class containing java.lang.CharSequence member variable反序列化包含 java.lang.CharSequence 成员变量的类
【发布时间】:2020-02-16 00:59:59
【问题描述】:

我有一个简单的类,其中包含name 类型为java.lang.CharSequence 的变量

    class Person {
    public java.lang.CharSequence name;
}

当我尝试使用 GSON 库反序列化 JSON 字符串时

        Person p;
        Gson gson = new Gson();
        String json = "{\"name\":\"dinesh\"}";
        p = gson.fromJson(json, Person.class);
        System.out.println(p);

它给了我以下错误:

java.lang.RuntimeException:无法为接口 java.lang.CharSequence 调用无参数构造函数。向 Gson 注册此类型的 InstanceCreator 可能会解决此问题。

我该如何解决这个问题?我无法将Person.name 类型更改为String。

按照 cmets 的建议,

我为CharSequence 创建了一个自定义适配器

class CharSequenceAdapter extends TypeAdapter<CharSequence> {

    @Override
    public void write(JsonWriter out, CharSequence value) throws IOException {
        
    }

    @Override
    public CharSequence read(JsonReader in) throws IOException {
        String s = new String();
        in.beginObject();
        while(in.hasNext()) {
            s = in.nextString();
        }
        return s;
    }
    
}

我的 GSON 构建器如下所示:

Person p;
GsonBuilder builder = new GsonBuilder().registerTypeAdapter(java.lang.CharSequence.class, new CharSequenceAdapter());
Gson gson = builder.create();
String json = "{\"name\":\"dinesh\"}";
p = gson.fromJson(json, Person.class);
System.out.println(p);

现在它给了我另一个错误:

预期为 BEGIN_OBJECT,但在第 1 行第 10 列路径 $.name 处为 STRING

我错过了什么?

我不认为它是重复的。所有其他问题都讨论了将一个类或接口作为一个整体进行反序列化。我遇到了一个将接口引用作为成员变量的类的问题。我无法从类似的答案中解决问题。

【问题讨论】:

    标签: java json serialization gson


    【解决方案1】:

    CharSequence 是一个接口。

    当 Gson 尝试将 json 字符串反序列化为对象时,它会“自省”该对象(通过使用反射)并尝试解析字段的类型。 然后它会尝试创建那个时间的字段。

    开箱即用的 Gson 可以处理许多“广泛”的类型,例如 String、Integer、Boolean 等,但是当 GSon 不知道它的某些东西时(如本例中的 CharSequence),GSon 会以 Error 停止。

    现在很明显,您应该“教”Gson 理解这种自定义类型。 为此,Gson 中有类型适配器。

    Here 您可以找到有关使用适配器的简短教程。 我不会从那里重新编写一个示例,但通常你应该创建一个适配器,在 Gson 对象上注册它并调用你的代码。当 Gson 到达 CharSequence 字段时,它会找到这个自定义适配器并调用它

    【讨论】:

    • 嗨,马克,我尝试添加自定义类型适配器,但仍然缺少一些东西...在描述中添加了我的 sn-p。
    【解决方案2】:

    您不需要in.beginObject(); 行。没有那行,代码可以正常工作。

    【讨论】:

      猜你喜欢
      • 2015-07-20
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      • 1970-01-01
      • 2022-08-21
      • 2020-10-12
      • 1970-01-01
      相关资源
      最近更新 更多