JSON Serialization Quiz

DATA › Networking

What mechanism does kotlinx.serialization use to produce serializers for @Serializable classes?

Answer: A Kotlin compiler plugin that generates code at compile time

kotlinx.serialization ships a Kotlin compiler plugin that generates a KSerializer per @Serializable type at compile time, avoiding runtime reflection and working across KMP targets.

A Kotlin data class is decoded with kotlinx.serialization and the JSON contains an extra field the class does not declare. With default settings, what happens?

Answer: A SerializationException is thrown

By default kotlinx.serialization is strict and throws on unknown keys; you must build Json { ignoreUnknownKeys = true } to skip them.

Which is the key advantage of Moshi's @JsonClass(generateAdapter = true) codegen over KotlinJsonAdapterFactory?

Answer: It skips kotlin-reflect and works without runtime reflection

Codegen generates adapters at compile time via KSP, so it does not pull in the ~2.5 MiB kotlin-reflect library and incurs no runtime reflection cost; the reflective factory is what needs kotlin-reflect.

In kotlinx.serialization, how do you rename a property so it maps to a differently-named JSON key?

Answer: Annotate the property with @SerialName("json_key")

@SerialName is the kotlinx.serialization annotation for renaming. @Json is Moshi and @SerializedName is Gson, so those are the wrong libraries.

A non-nullable Kotlin property has no default value, and the incoming JSON omits its key. In kotlinx.serialization, what is the result?

Answer: Decoding throws a MissingFieldException

With no default and a non-nullable type, a missing key cannot be satisfied, so kotlinx.serialization throws MissingFieldException; only properties with defaults or nullable types tolerate absence.

Why is Gson considered a legacy choice for new Kotlin Android code compared to kotlinx.serialization and Moshi?

Answer: Reflection-based, ignores Kotlin nullability, and unmaintained

Gson uses runtime reflection, can instantiate non-null Kotlin properties as null and skips default values, and is no longer actively developed, which makes it risky for Kotlin code.

What is the standard way to serialize a sealed class hierarchy polymorphically with kotlinx.serialization?

Answer: Mark parent and subclasses @Serializable; a discriminator selects it

Marking the sealed parent and its subclasses @Serializable lets the plugin emit a class discriminator (default key 'type') that encodes and selects the correct subtype; RuntimeTypeAdapterFactory and @JsonClass belong to other libraries.

In kotlinx.serialization, how do you exclude a property of a @Serializable class from being serialized and deserialized?

Answer: Mark it with @Transient and give it a default value

@Transient excludes a property from serialization, and the property must have a default value because it will never be read from JSON. @Json is Moshi and @Expose is Gson.

By default kotlinx.serialization does not write a property whose value equals its declared default. How do you force those defaults to be emitted?

Answer: Set encodeDefaults = true on Json, or use @EncodeDefault

encodeDefaults defaults to false, so values equal to the default are skipped; setting encodeDefaults = true on the Json config (or @EncodeDefault on a property) forces them to be written.

You need non-default encoding for a type you do not own, such as java.time.Instant, in kotlinx.serialization. What is the idiomatic approach?

Answer: Implement KSerializer<Instant>, attach via @Serializable(with=)

For types you do not own or that need custom encoding, you implement KSerializer<T> and attach it with @Serializable(with=) or contextual serialization; GsonBuilder and @JsonClass belong to other libraries.

An evolving API sometimes sends JSON null for a field that maps to a non-nullable Kotlin property which has a default value. Which Json setting lets decoding fall back to the default instead of throwing?

Answer: coerceInputValues = true, falling back to the default

coerceInputValues = true coerces an invalid or null input for a property that has a default into that default value; isLenient only relaxes quoting and ignoreUnknownKeys only skips unknown keys.

Which annotation processor does modern Moshi use to run @JsonClass(generateAdapter = true) codegen on Android?

Answer: KSP (Kotlin Symbol Processing)

Modern Moshi codegen runs through KSP for faster, Kotlin-aware processing; the generated XxxJsonAdapter is then discovered automatically by Moshi at runtime.

How do you wire a kotlinx.serialization Json instance into Retrofit as the body converter?

Answer: Add Json.asConverterFactory(...) from the serialization converter

Retrofit integrates with kotlinx.serialization via the converter that exposes Json.asConverterFactory(...); the Gson and Moshi factories are for those libraries, and Retrofit has no built-in @Serializable support.

A server renamed a JSON key from 'login' to 'username' but still emits the old key for some clients. In kotlinx.serialization, how can one Kotlin property accept either key when decoding?

Answer: Annotate the property with @JsonNames("username", "login")

@JsonNames declares additional accepted input names for a property during decoding, so both 'username' and 'login' deserialize into the same property; @SerialName accepts only a single name.

Back to JSON Serialization