我有一个对象列表,我需要将其反序列化到正确的子类中。我已经能够通过构建像下面的
这样的gson对象来实现这一点 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();
虽然它有效但必须有更好的方法。目前我正在我的GsonBuilder中创建一个Gson实例。让人惊讶。有没有办法可以使用我要构建的Gson对象来反序列化不同的子类型?
答案 0 :(得分:1)
如果我正确理解了这个问题,您可以直接使用JsonDeserializationContext
。
return jsonContext.deserialize(json, classOfType(type));
classOfType()
应该返回与您的形状的type
对应的类。
答案 1 :(得分:1)
无需重新发明轮子。你的问题在Gson的范围内是经典的,并且有一个特殊的RuntimeTypeAdapterFactory
旨在解决这种类型的问题。例如,如果你有这样的东西:
final class Types {
private Types() {
}
static final int TYPE_CARD = 1;
static final int TYPE_BLOCK = 2;
static final int TYPE_STRIPE = 3;
abstract static class Abstract {
private Abstract() { }
static final class Card extends Abstract { }
static final class Block extends Abstract { }
static final class Stripe extends Abstract {}
}
}
您可以配置和使用RuntimeTypeAdapterFactory
:
private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(
RuntimeTypeAdapterFactory.of(Types.Abstract.class, "type")
.registerSubtype(Types.Abstract.Card.class, String.valueOf(Types.TYPE_CARD))
.registerSubtype(Types.Abstract.Block.class, String.valueOf(Types.TYPE_BLOCK))
.registerSubtype(Types.Abstract.Stripe.class, String.valueOf(Types.TYPE_STRIPE))
)
.create();
然后你甚至不需要任何其他东西:
private static final Type abstractListType = new TypeToken<List<Types.Abstract>>() {
}.getType();
public static void main(final String... args) {
gson.<List<Types.Abstract>>fromJson("[{\"type\":1},{\"type\":2},{\"type\":3}]", abstractListType)
.stream()
.map(Types.Abstract::getClass)
.forEach(System.out::println);
}
输出:
class q43159721.Types $ Abstract $ Card
class q43159721.Types $ Abstract $ Block
class q43159721.Types $ Abstract $ Stripe