gpt4 book ai didi

android - JSON(Gson)反序列化为父类(super class)对象然后转换为子类对象的最佳方法是什么

转载 作者:搜寻专家 更新时间:2023-11-01 08:01:51 25 4
gpt4 key购买 nike

我目前正在研究在Android上使用Gson for Json,刚遇到这个问题。假设我们有如下类:

    class Command {
public int id = COMMAND_ID_UNSPECIFIED;
}

class CommandSpecific1 extends Command{
public String specialStr;
public CommandSpecific1 () {
id = COMMAND_ID_SPECIAL1;
specialStr= "special";
}
}
class CommandSpecific2 extends Command{
public int specialInt;
public CommandSpecific2 () {
id = COMMAND_ID_SPECIAL2;
specialInt = 3.1415926;
}
}

我使用以下代码创建 Json 字符串

CommandSpecific specialCmd = new CommandSpecific();
Gson gson = new Gson();
String json = gson.toJson(specialCmd);

现在我想做这样的事情(错误的代码)

Command genericCmd = gson.fromJson(json, Command.class)
if(genericCmd.id == COMMAND_ID_SPECIAL1) {
CommandSpecific1 cmd1 = (CommandSpecific1)genericCmd;
//do sth with cmd1.specialStr
} else if(genericCmd.id == COMMAND_ID_SPECIAL2) {
CommandSpecific2 cmd2 = (CommandSpecific2)genericCmd;
//do sth with cmd2.specialInt
}

代码不起作用,因为 gson.fromJson(json, Command.class) 只为父类(super class)创建对象。我知道我可以调用 fromJson 并指定真实的类类型,但是有没有更好的方法呢?我应该使用定制的反序列化方法来解决这个问题吗?怎么办?

最佳答案

我会尝试像这个准备运行的例子那样反序列化。作为评论,您不想使用 id 字段在命令之间切换,因此您必须信任字段结构并假设每个子类都存在一个唯一标识您的子类的字段组合。

package stackoverflow.questions.q20185625;

import java.lang.reflect.Type;

import com.google.gson.*;

public class Q20185625 {

public static class Command {
public int id = -1;
}

public static class CommandSpecific1 extends Command {
public String specialStr;

public CommandSpecific1() {
id = 1;
specialStr = "special";
}
}

public static class CommandSpecific2 extends Command {
public int specialInt;

public CommandSpecific2() {
id = 2;
specialInt = 42;
}
}

public static class CustomDeserializer implements JsonDeserializer<Command> {

public Command deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

if (json == null)
return null;
else {
JsonElement e = json.getAsJsonObject().get("specialStr");
if (e != null && e.isJsonPrimitive() && e.getAsString() instanceof String) {
CommandSpecific1 c = new CommandSpecific1();
c.specialStr = e.getAsString(); // do you need this?
return c;
}

e = json.getAsJsonObject().get("specialInt");
if (e != null && e.isJsonPrimitive() && e.getAsNumber() instanceof Number) {
CommandSpecific2 c = new CommandSpecific2();
c.specialInt = e.getAsInt(); // do you need this?
return c;
}
return null; // or throw an IllegalArgumentException

}

}

}

public static void main(String[] args) {
GsonBuilder gb = new GsonBuilder();
gb.registerTypeAdapter(Command.class, new CustomDeserializer());
Gson customGson = gb.create();

String jsonTest1 = "{\"specialStr\":\"AA\"}";
String jsonTest2 = "{\"specialInt\":13}";
String jsonTest3 = "{}";
String jsonTest4 = "";

System.out.println("Deserialize test 1: " + customGson.fromJson(jsonTest1, Command.class));
System.out.println("Deserialize test 2: " + customGson.fromJson(jsonTest2, Command.class));
System.out.println("Deserialize test 3: " + customGson.fromJson(jsonTest3, Command.class));
System.out.println("Deserialize test 4: " + customGson.fromJson(jsonTest4, Command.class));

}

}

这就是结果(我避免使用 toString,向您展示类类型)

Deserialize test 1: stackoverflow.questions.qww.Q20185625$CommandSpecific1@30d5aa
Deserialize test 2: stackoverflow.questions.qww.Q20185625$CommandSpecific2@13552ed
Deserialize test 3: null
Deserialize test 4: null

编辑如果您的 JSON 还包含 id 字段,则更容易。您始终可以使用 TypeAdapter,但要以一种直接的方式:

public static class CustomDeserializer implements JsonDeserializer<Command> {

public Command deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

if (json == null)
return null;
else {
// null management can be improved
int id = json.getAsJsonObject().get("id").getAsInt();
switch(id){
case COMMAND_TYPE_1:
return context.deserialize(json, CommandSpecific1.class);
case COMMAND_TYPE_2:
return context.deserialize(json, CommandSpecific2.class);
default:
return null;
}
}

}

}

但是,如果您对 JSON 的其余部分感兴趣并且担心性能(但这不是原始问题,您询问的是子类化问题),您可以尝试 TypeAdapter

关于android - JSON(Gson)反序列化为父类(super class)对象然后转换为子类对象的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20185625/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com