Android 构建一个可以膨胀子类的Gson实例
我有一个对象列表,我需要将其反序列化为适当的子类。我已经能够通过构建一个gson对象来实现这一点,如下所示Android 构建一个可以膨胀子类的Gson实例,android,json,inheritance,serialization,gson,Android,Json,Inheritance,Serialization,Gson,我有一个对象列表,我需要将其反序列化为适当的子类。我已经能够通过构建一个gson对象来实现这一点,如下所示 JsonDeserializer<Shape> jdTypes = (json, typeOfT, jsonContext) -> { JsonObject jsonObject = json.getAsJsonObject(); int type = jsonObject.get("type").getAsInt();
JsonDeserializer<Shape> jdTypes = (json, typeOfT, jsonContext) -> {
JsonObject jsonObject = json.getAsJsonObject();
int type = jsonObject.get("type").getAsInt();
Gson gson = new Gson();
switch (type){
case Types.TYPE_CARD:
return gson.fromJson(json, Card.class);
case Types.TYPE_BLOCK:
return gson.fromJson(json, Block.class);
case Types.TYPE_STRIPE:
return gson.fromJson(json, Stripe.class);
//...
}
};
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Shape.class, jdTypes);
builder.create();
JsonDeserializer jdTypes=(json、typeOfT、jsonContext)->{
JsonObject JsonObject=json.getAsJsonObject();
int type=jsonObject.get(“type”).getAsInt();
Gson Gson=新的Gson();
开关(类型){
案例类型。类型\卡:
返回gson.fromJson(json,Card.class);
案例类型。案例类型块:
返回gson.fromJson(json,Block.class);
案例类型。类型\u条带:
返回gson.fromJson(json,Stripe.class);
//...
}
};
GsonBuilder=新的GsonBuilder();
registerTypeAdapter(Shape.class,jdTypes);
builder.create();
虽然它正在发挥作用,但必须有更好的方法。目前,我正在我的GsonBuilder中创建一个Gson实例。哎呀。有没有一种方法可以使用我将要构建的Gson对象来反序列化不同的子类型?如果我正确理解这个问题,您可以直接使用
JsonDeserializationContext
return jsonContext.deserialize(json, classOfType(type));
其中
classOfType()
应该只返回与您形状的类型
对应的类。如果我正确理解这个问题,您可以直接使用JsonDeserializationContext
return jsonContext.deserialize(json, classOfType(type));
其中
classOfType()
应该只返回与您形状的类型
对应的类。无需重新发明轮子。您的问题是Gson范围内的经典问题,并且有一个专门设计用于解决此类问题的特殊问题。例如,如果您有如下内容:
最终类类型{
私有类型(){
}
静态最终整数类型\ U卡=1;
静态最终整型块=2;
静态最终整数类型_STRIPE=3;
抽象静态类抽象{
私有抽象(){}
静态最终类卡片扩展了抽象{}
静态最终类块扩展了抽象{}
静态最终类条带扩展了抽象{}
}
}
您可以配置和使用RuntimeTypeAdapterFactory
:
private static final Gson Gson=new GsonBuilder()
.registerTypeAdapterFactory(
RuntimeTypeAdapterFactory.of(Types.Abstract.class,“type”)
.registerSubtype(Types.Abstract.Card.class,String.valueOf(Types.TYPE\u Card))
.registerSubtype(Types.Abstract.Block.class、String.valueOf(Types.TYPE\u Block))
.registerSubtype(Types.Abstract.Stripe.class、String.valueOf(Types.TYPE\u Stripe))
)
.create();
那么你甚至不需要任何其他东西:
私有静态最终类型abstractListType=new-TypeToken(){
}.getType();
公共静态void main(最终字符串…参数){
fromJson(“[{\'type\':1},{\'type\':2},{\'type\':3}]”,abstractListType)
.stream()
.map(类型.Abstract::getClass)
.forEach(System.out::println);
}
输出:
q43159721类。类型$Abstract$卡q43159721类。类型$Abstract$Block
类q43159721.类型$Abstract$Stripe
不需要重新发明轮子。您的问题是Gson范围内的经典问题,并且有一个专门设计用于解决此类问题的特殊问题。例如,如果您有如下内容:
最终类类型{
私有类型(){
}
静态最终整数类型\ U卡=1;
静态最终整型块=2;
静态最终整数类型_STRIPE=3;
抽象静态类抽象{
私有抽象(){}
静态最终类卡片扩展了抽象{}
静态最终类块扩展了抽象{}
静态最终类条带扩展了抽象{}
}
}
您可以配置和使用RuntimeTypeAdapterFactory
:
private static final Gson Gson=new GsonBuilder()
.registerTypeAdapterFactory(
RuntimeTypeAdapterFactory.of(Types.Abstract.class,“type”)
.registerSubtype(Types.Abstract.Card.class,String.valueOf(Types.TYPE\u Card))
.registerSubtype(Types.Abstract.Block.class、String.valueOf(Types.TYPE\u Block))
.registerSubtype(Types.Abstract.Stripe.class、String.valueOf(Types.TYPE\u Stripe))
)
.create();
那么你甚至不需要任何其他东西:
私有静态最终类型abstractListType=new-TypeToken(){
}.getType();
公共静态void main(最终字符串…参数){
fromJson(“[{\'type\':1},{\'type\':2},{\'type\':3}]”,abstractListType)
.stream()
.map(类型.Abstract::getClass)
.forEach(System.out::println);
}
输出:
q43159721类。类型$Abstract$卡q43159721类。类型$Abstract$Block
类q43159721.类型$Abstract$Stripe
知道为什么RuntimeTypeAdapterFactory不是定义的类型吗?@Canoe
RuntimeTypeAdapterFactory
是Gson extras的一部分,而不是主库,因此不会发布到Maven Central。复制/粘贴或注册如下内容:Thanks我想我可能是一个额外的软件包,但我正在寻找一个由google编写的软件包。看起来这是第三方的扩展。感谢s@Canoe嗯,如果它是官方Gson源代码库的一部分,那么它本身就不是第三方扩展。:)老实说,我不确定将原始源代码包含到代码库中是否合法(我真的很害怕任何版权头lol)。但是,添加第三方库(如org.danilopianini:gson extras:0.1.0
)绝对是一个优先级最低的选择。知道为什么RuntimeTypeAdapterFactory不是一个定义的类型吗?@CanoeRunt