Wenn Sie aus dem Deserialisierung Kontext (im Sinne der mehr Operationen, nicht nur gson.fromJson(...)
, in einer Call-Website), können Sie die Antwort jdebon verwenden. Wenn Sie es innerhalb des Deserialisierungsprozesses erkennen, können Sie einen benutzerdefinierten Typadapter erstellen (nur wenn Sie eine gemeinsame Basisklasse aufgrund grundlegender Gson-Einschränkungen haben, die das Binden von java.lang.Object
verbieten). Zum Beispiel:
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (jsonElement, type, context) -> {
final JsonObject jsonObject = jsonElement.getAsJsonObject();
final boolean hasImage = jsonObject.has("image");
final boolean hasTime = jsonObject.has("time");
if (hasImage && hasTime) {
throw new JsonParseException("Cannot handle both image and time");
}
if (hasImage) {
return context.deserialize(jsonElement, Image.class);
}
if (hasTime) {
return context.deserialize(jsonElement, Time.class);
}
throw new JsonParseException("Cannot parse " + jsonElement);
})
.create();
abstract class Base {
final int id = Integer.valueOf(0);
final String name = null;
}
final class Image
extends Base {
final String image = null;
}
final class Time
extends Base {
final String time = null;
}
Beispiel:
for (final String resource : ImmutableList.of("image.json", "time.json")) {
try (final JsonReader jsonReader = getPackageResourceJsonReader(Q44227327.class, resource)) {
final Base base = gson.fromJson(jsonReader, Base.class);
System.out.println(base.getClass().getSimpleName());
}
}
Ausgang:
Bild
Zeit