Class PolymorphicJsonAdapterFactory<T>
- java.lang.Object
-
- com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory<T>
-
- All Implemented Interfaces:
com.squareup.moshi.JsonAdapter.Factory
public final class PolymorphicJsonAdapterFactory<T> extends java.lang.Object implements com.squareup.moshi.JsonAdapter.FactoryA JsonAdapter factory for objects that include type information in the JSON. When decoding JSON Moshi uses this type information to determine which class to decode to. When encoding Moshi uses the object’s class to determine what type information to include.Suppose we have an interface, its implementations, and a class that uses them:
interface HandOfCards { } class BlackjackHand implements HandOfCards { Card hidden_card; List<Card> visible_cards; } class HoldemHand implements 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
HandOfCardsinterface. 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:
- Base types may be classes or interfaces.
- Subtypes must encode as JSON objects.
- Type information must be in the encoded object. Each message must have a type label like
hand_typewhose value is a string likeblackjackthat identifies which type to use. - Each type identifier must be unique.
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:
- If
withDefaultValue(Object)is used, thendefaultValuewill be returned. - If
withFallbackJsonAdapter(JsonAdapter)is used, then thefallbackJsonAdapter.fromJson(reader)result will be returned. - Otherwise a
JsonDataExceptionwill be thrown.
If an unknown type is encountered when encoding:
- If
withFallbackJsonAdapter(JsonAdapter)is used, then thefallbackJsonAdapter.toJson(writer, value)result will be returned. - Otherwise a
IllegalArgumentExceptionwill be thrown.
If the same subtype has multiple labels the first one is used when encoding.
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description com.squareup.moshi.JsonAdapter<?>create(java.lang.reflect.Type type, java.util.Set<? extends java.lang.annotation.Annotation> annotations, com.squareup.moshi.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 will default todefaultValueupon decoding of unrecognized labels.PolymorphicJsonAdapterFactory<T>withFallbackJsonAdapter(com.squareup.moshi.JsonAdapter<java.lang.Object> fallbackJsonAdapter)Returns a new factory that with default tofallbackJsonAdapter.fromJson(reader)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 ofsubtype.
-
-
-
Method Detail
-
of
@CheckReturnValue public static <T> PolymorphicJsonAdapterFactory<T> of(java.lang.Class<T> baseType, java.lang.String labelKey)
- Parameters:
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.
-
withSubtype
public PolymorphicJsonAdapterFactory<T> withSubtype(java.lang.Class<? extends T> subtype, java.lang.String label)
Returns a new factory that decodes instances ofsubtype.
-
withFallbackJsonAdapter
public PolymorphicJsonAdapterFactory<T> withFallbackJsonAdapter(@Nullable com.squareup.moshi.JsonAdapter<java.lang.Object> fallbackJsonAdapter)
Returns a new factory that with default tofallbackJsonAdapter.fromJson(reader)upon decoding of unrecognized labels.The
JsonReaderinstance will not be automatically consumed, so sure to consume it within your implementation ofJsonAdapter.fromJson(JsonReader)
-
withDefaultValue
public PolymorphicJsonAdapterFactory<T> withDefaultValue(@Nullable T defaultValue)
Returns a new factory that will default todefaultValueupon decoding of unrecognized labels. The default value should be immutable.
-
create
public com.squareup.moshi.JsonAdapter<?> create(java.lang.reflect.Type type, java.util.Set<? extends java.lang.annotation.Annotation> annotations, com.squareup.moshi.Moshi moshi)- Specified by:
createin interfacecom.squareup.moshi.JsonAdapter.Factory
-
-