Сериализация классов
Аннотация @Serializable включает сериализацию по умолчанию всех свойств класса с полями хранения. Вы можете настроить это поведение в соответствии со своими потребностями. На этой странице рассматриваются различные способы сериализации: вы узнаете, как указать, какие свойства сериализуются, и как управлять процессом сериализации.
Перед началом убедитесь, что вы подключили необходимые зависимости библиотеки.
Аннотация @Serializable
Аннотация @Serializable включает автоматическую сериализацию свойств класса, позволяя преобразовывать класс в такие форматы, как JSON, и обратно.
В Kotlin сериализуются только свойства с полями хранения:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
class Project(
// Property with a backing field – serialized
var name: String
) {
// Property with a backing field – serialized
var stars: Int = 0
// Getter-only property without a backing field - not serialized
val path: String
get() = "kotlin/$name"
// Delegated property - not serialized
var id by ::name
}
fun main() {
val data = Project("kotlinx.serialization").apply { stars = 9000 }
// Prints only the name and the stars properties
println(Json.encodeToString(data))
// {"name":"kotlinx.serialization","stars":9000}
}
//sampleEnd
Сериализация ссылок на классы
Классы с аннотацией @Serializable могут содержать свойства, ссылающиеся на другие классы. Эти классы также должны иметь аннотацию @Serializable. При кодировании в JSON это приводит к появлению вложенного объекта JSON:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
// The owner property references another serializable class User
class Project(val name: String, val owner: User)
// The referenced class must also be annotated with @Serializable
@Serializable
class User(val name: String)
fun main() {
val owner = User("kotlin")
val data = Project("kotlinx.serialization", owner)
println(Json.encodeToString(data))
// {"name":"kotlinx.serialization","owner":{"name":"kotlin"}}
}
//sampleEnd
Сериализация повторяющихся ссылок на объекты
Сериализация Kotlin предназначена для кодирования и декодирования простых данных. Она не поддерживает восстановление произвольных графов объектов с повторяющимися ссылками на объекты. Например, при сериализации объекта, который дважды ссылается на один и тот же экземпляр, он кодируется дважды:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
class Project(val name: String, val owner: User, val maintainer: User)
@Serializable
class User(val name: String)
fun main() {
val owner = User("kotlin")
// References owner twice
val data = Project("kotlinx.serialization", owner, owner)
println(Json.encodeToString(data))
// {"name":"kotlinx.serialization","owner":{"name":"kotlin"},"maintainer":{"name":"kotlin"}}
}
//sampleEnd
Сериализация обобщённых классов
Обобщённые классы в Kotlin поддерживают полиморфизм типов, который сериализация Kotlin обеспечивает во время компиляции. Например, рассмотрим обобщённый сериализуемый класс Payload<T>:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
// The Payload<T> class can be used with built-in types like Int
// or with @Serializable user-defined types like Repository
class Payload<T>(val value: T)
@Serializable
data class Repository(val name: String, val language: String)
@Serializable
class BackupData(
val issueCount: Payload<Int>,
val mainRepo: Payload<Repository>
)
fun main() {
val backup = BackupData(
Payload(42),
Payload(Repository("kotlinx.serialization", "Kotlin"))
)
println(Json.encodeToString(backup))
// {"issueCount":{"value":42},"mainRepo":{"value":{"name":"kotlinx.serialization","language":"Kotlin"}}}
}
//sampleEnd
При сериализации обобщённого класса, например Box<T>, результат в формате JSON зависит от фактического типа, указанного для T во время компиляции. Если этот тип не сериализуем, возникает ошибка компиляции.
Необязательные свойства
Свойства со значениями по умолчанию являются необязательными при десериализации и могут пропускаться при сериализации, если формат настроен соответствующим образом. Например, конфигурация JSON по умолчанию пропускает кодирование значений по умолчанию.
Задание значений по умолчанию для необязательных свойств
В Kotlin десериализовать объект можно только в том случае, если во входных данных присутствуют все его свойства. Чтобы сделать свойство необязательным при сериализации, задайте значение по умолчанию, которое будет использоваться, если во входных данных значение не указано:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
// Sets a default value for the optional language property
data class Project(val name: String, val language: String = "Kotlin")
fun main() {
val data = Json.decodeFromString<Project>("""
{"name":"kotlinx.serialization"}
""")
println(data)
// Project(name=kotlinx.serialization, language=Kotlin)
}
//sampleEnd
Сериализация свойств, допускающих значение null
Сериализация Kotlin изначально поддерживает свойства, допускающие значение null. Как и другие значения по умолчанию, значения null не кодируются в выводе JSON:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
// Defines a class with the renamedTo nullable property that has a null default value
class Project(val name: String, val renamedTo: String? = null)
fun main() {
val data = Project("kotlinx.serialization")
// The renamedTo property isn't encoded because its value is null
println(Json.encodeToString(data))
// {"name":"kotlinx.serialization"}
}
//sampleEnd
Кроме того, при десериализации строго соблюдается безопасность null в Kotlin. Если объект JSON содержит значение null для свойства, не допускающего значение null, возникает исключение, даже если у свойства есть значение по умолчанию:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
data class Project(val name: String, val language: String = "Kotlin")
fun main() {
val data = Json.decodeFromString<Project>("""
{"name":"kotlinx.serialization","language":null}
""")
println(data)
// JsonDecodingException
}
//sampleEnd
Инициализаторы необязательных свойств
Если во входных данных для сериализации указано значение необязательного свойства, инициализатор этого свойства не вызывается. Поэтому не используйте в инициализаторах свойств код с побочными эффектами.
Пример:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
fun computeLanguage(): String {
println("Computing")
return "Kotlin"
}
@Serializable
// Skips the initializer if language is in the input
data class Project(val name: String, val language: String = computeLanguage())
fun main() {
val data = Json.decodeFromString<Project>("""
{"name":"kotlinx.serialization","language":"Java"}
""")
println(data)
// Project(name=kotlinx.serialization, language=Java)
}
//sampleEnd
В этом примере, поскольку во входных данных указано свойство language, строка Computing не выводится.
Управление сериализацией свойств со значениями по умолчанию с помощью @EncodeDefault
По умолчанию при сериализации в JSON исключаются свойства со значениями по умолчанию. Это уменьшает размер сериализованных данных и позволяет избежать лишнего визуального шума.
В следующем примере свойство language исключается из вывода, поскольку его значение совпадает со значением по умолчанию:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
data class Project(val name: String, val language: String = "Kotlin")
fun main() {
val data = Project("kotlinx.serialization")
println(Json.encodeToString(data))
// {"name":"kotlinx.serialization"}
}
//sampleEnd
Чтобы всегда сериализовать свойство независимо от его значения и настроек формата, используйте аннотацию @EncodeDefault. В качестве альтернативы можно изменить это поведение, задав параметр EncodeDefault.Mode.
Рассмотрим пример, в котором свойство language всегда включается в сериализованный результат, а свойство projects исключается, если оно представляет собой пустой список:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.EncodeDefault.Mode.NEVER
//sampleStart
@Serializable
data class Project(
val name: String,
// Always includes the language property in the serialized output
// even if it has the default value "Kotlin"
@EncodeDefault val language: String = "Kotlin"
)
@Serializable
data class User(
val name: String,
// Excludes projects when it's an empty list, even if it has a default value
@EncodeDefault(NEVER) val projects: List<Project> = emptyList()
)
fun main() {
val adminUser = User("Alice", listOf(Project("kotlinx.serialization")))
val guestUser = User("Bob")
// Serializes projects because it contains a value
// language is always serialized
println(Json.encodeToString(adminUser))
// {"name":"Alice","projects":[{"name":"kotlinx.serialization","language":"Kotlin"}]}
// Excludes projects because it's an empty list
// and EncodeDefault.Mode is set to NEVER, so it's not serialized
println(Json.encodeToString(guestUser))
// {"name":"Bob"}
}
//sampleEnd
Обязательные свойства с аннотацией @Required
Пометьте свойство аннотацией @Required, чтобы сделать его обязательным во входных данных. Это гарантирует, что свойство будет присутствовать во входных данных, даже если у него есть значение по умолчанию:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.Required
//sampleStart
@Serializable
// Marks the language property as required
data class Project(val name: String, @Required val language: String = "Kotlin")
fun main() {
val data = Json.decodeFromString<Project>("""
{"name":"kotlinx.serialization"}
""")
println(data)
// MissingFieldException
}
//sampleEnd
Настройка сериализации классов
Сериализация Kotlin предоставляет несколько способов изменить сериализацию классов. В этом разделе описываются способы настройки имён свойств, управления включением свойств и многое другое.
Настройка сериализуемых имён
По умолчанию имена свойств в результате сериализации, например в JSON, совпадают с их именами в исходном коде.
Вы можете настроить эти имена, называемые сериализуемыми именами, с помощью аннотации @SerialName. Используйте её, чтобы сделать имя свойства в сериализованном результате более понятным:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
// Changes the lang property to language using @SerialName
class Project(val name: String, @SerialName("language") val lang: String)
fun main() {
val data = Project("kotlinx.serialization", "Kotlin")
// Prints the more descriptive property name in the JSON output
println(Json.encodeToString(data))
// {"name":"kotlinx.serialization","language":"Kotlin"}
}
//sampleEnd
Определение свойств конструктора для сериализации
Класс с аннотацией @Serializable должен объявлять все параметры первичного конструктора в качестве свойств.
Если перед присваиванием значений свойствам необходимо выполнить дополнительную логику инициализации, используйте вторичный конструктор. Первичный конструктор может оставаться private и отвечать за инициализацию свойств.
В следующем примере вторичный конструктор разбирает строку на два значения, которые затем передаются первичному конструктору для сериализации:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
class Project private constructor(val owner: String, val name: String) {
// Creates a Project object using a path string
constructor(path: String) : this(
owner = path.substringBefore('/'),
name = path.substringAfter('/')
)
val path: String
get() = "$owner/$name"
}
fun main() {
println(Json.encodeToString(Project("kotlin/kotlinx.serialization")))
// {"owner":"kotlin","name":"kotlinx.serialization"}
}
//sampleEnd
Проверка данных в первичном конструкторе
После десериализации плагин kotlinx.serialization выполняет блоки инициализации класса так же, как при создании экземпляра. Это позволяет проверять параметры конструктора и отклонять недопустимые данные во время десериализации.
Пример:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.json.*
//sampleStart
@Serializable
class Project(val name: String) {
// Validates that the name is not empty
init {
require(name.isNotEmpty()) { "name cannot be empty" }
}
}
fun main() {
val data = Json.decodeFromString<Project>("""
{"name":""}
""")
println(data)
// Exception in thread "main" java.lang.IllegalArgumentException: name cannot be empty
}
//sampleEnd
Исключение свойств с помощью аннотации @Transient
Свойство можно исключить из сериализации с помощью аннотации @Transient. У временных свойств должно быть значение по умолчанию.
Если явно указать во входных данных значение временного свойства, даже совпадающее со значением по умолчанию, будет выброшено исключение JsonDecodingException:
// Imports declarations from the serialization library
import kotlinx.serialization.*
import kotlinx.serialization.Transient
import kotlinx.serialization.json.*
//sampleStart
@Serializable
// Excludes the language property from serialization
data class Project(val name: String, @Transient val language: String = "Kotlin")
fun main() {
// Throws an exception even though input matches the default value
val data = Json.decodeFromString<Project>("""
{"name":"kotlinx.serialization","language":"Kotlin"}
""")
println(data)
// JsonDecodingException
}
//sampleEnd
Что дальше
Узнайте о более сложных сценариях сериализации JSON в обзоре сериализации JSON.
Узнайте, как получать сгенерированные сериализаторы, создавать собственные сериализаторы и применять их, в разделе Создание и использование сериализаторов.
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/serialization-customization-options.html