我有一个简单的类,包含java.lang.CharSequence
类型的name
变量
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
。
正如评论中所建议的,
我为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);
现在它又给了我一个错误:
路径$.name的第1行第10列应为开始_OBJECT,但为STRING
我错过了什么?
我不认为这是一个重复。所有其他问题都是关于将一个类或接口作为一个整体进行反序列化。我遇到了一个问题,这个类将接口引用作为成员变量。我无法从类似的答案中解决这个问题。
3条答案
按热度按时间thtygnil1#
CharSequence是一个接口。
当Gson试图将一个json字符串反序列化为一个对象时,它会“内省”该对象(通过使用反射),并试图解析字段的类型,然后它会尝试创建当时的字段。
开箱即用,Gson可以处理许多“广泛”的类型,如String、Integer、Boolean等,然而,当它的一些东西GSon是不知道的(如在这种情况下的CharSequence),GSon停止与错误。
现在很清楚,你应该“教”Gson理解这个自定义类型。为此,Gson中有类型适配器。
Here你可以找到一个关于使用适配器的简短教程。我不会在这里重新编写一个例子,但是一般来说你应该创建一个适配器,在Gson对象上注册它并调用你的代码。当Gson到达CharSequence字段时,它会找到这个自定义适配器并调用它
km0tfn4u2#
正如在其他答案中提到的,Gson没有
CharSequence
的内置适配器(请参见related pull request),因此无法对其进行反序列化。但是,您可以通过编写自定义
TypeAdapter
来解决此问题,如下所示:这假设您的
CharSequence
值被编码为JSON字符串值(例如"value"
),而不是JSON对象({ ... }
)。对于序列化,它还假设您使用的值符合CharSequence.toString()
协定。您必须使用
GsonBuilder
注册该适配器,然后使用该适配器创建Gson
示例:或者,如果您实际上始终使用
String
作为CharSequence
值,那么您也可以将字段类型更改为String
,以防这对代码的API没有任何负面影响。xxe27gdn3#
您不需要
in.beginObject();
行,没有这行代码就可以正常工作。