public final class PolymorphicJsonAdapterFactory<T> extends java.lang.Object implements JsonAdapter.Factory
Suppose we have an interface, its implementations, and a class that uses them:
interface HandOfCards {
}
class BlackjackHand extends HandOfCards {
Card hidden_card;
List<Card> visible_cards;
}
class HoldemHand extends HandOfCards {
Set<Card> hidden_cards;
}
class Player {
String name;
HandOfCards hand;
}
We want to decode the following JSON into the player model above:
{
"name": "Jesse",
"hand": {
"hand_type": "blackjack",
"hidden_card": "9D",
"visible_cards": ["8H", "4C"]
}
}
Left unconfigured, Moshi would incorrectly attempt to decode the hand object to the abstract
HandOfCards interface. We configure it to use the appropriate subtype instead:
Moshi moshi = new Moshi.Builder()
.add(PolymorphicJsonAdapterFactory.of(HandOfCards.class, "hand_type")
.withSubtype(BlackjackHand.class, "blackjack")
.withSubtype(HoldemHand.class, "holdem"))
.build();
This class imposes strict requirements on its use:
hand_type whose value is a string like blackjack that identifies which type
to use.
For best performance type information should be the first field in the object. Otherwise Moshi must reprocess the JSON stream once it knows the object's type.
If an unknown subtype is encountered when decoding, this will throw a JsonDataException. If an unknown type is encountered when encoding, this will throw an IllegalArgumentException. If the same subtype has multiple labels the first one is used when
encoding.
If you want to specify a custom unknown fallback for decoding, you can do so via
withDefaultValue(Object). This instance should be immutable, as it is shared.
| Modifier and Type | Method and Description |
|---|---|
JsonAdapter<?> |
create(java.lang.reflect.Type type,
java.util.Set<? extends java.lang.annotation.Annotation> annotations,
Moshi moshi) |
static <T> PolymorphicJsonAdapterFactory<T> |
of(java.lang.Class<T> baseType,
java.lang.String labelKey) |
PolymorphicJsonAdapterFactory<T> |
withDefaultValue(T defaultValue)
Returns a new factory that with default to
defaultValue upon decoding of unrecognized
labels. |
PolymorphicJsonAdapterFactory<T> |
withSubtype(java.lang.Class<? extends T> subtype,
java.lang.String label)
Returns a new factory that decodes instances of
subtype. |
@CheckReturnValue public static <T> PolymorphicJsonAdapterFactory<T> of(java.lang.Class<T> baseType, java.lang.String labelKey)
baseType - The base type for which this factory will create adapters. Cannot be Object.labelKey - The key in the JSON object whose value determines the type to which to map the
JSON object.public PolymorphicJsonAdapterFactory<T> withSubtype(java.lang.Class<? extends T> subtype, java.lang.String label)
subtype. When an unknown type is found
during encoding an IllegalArgumentException will be thrown. When an unknown label
is found during decoding a JsonDataException will be thrown.public PolymorphicJsonAdapterFactory<T> withDefaultValue(@Nullable T defaultValue)
defaultValue upon decoding of unrecognized
labels. The default value should be immutable.public JsonAdapter<?> create(java.lang.reflect.Type type, java.util.Set<? extends java.lang.annotation.Annotation> annotations, Moshi moshi)
create in interface JsonAdapter.FactoryCopyright © 2019. All Rights Reserved.