kotlinx.serialization: bu nima, annotatsiyalar va JSON serializatsiyasi

Muallif: IT Sectr Nashr etilgan: 2026-03-15 O'qish vaqti: 12 daq

kotlinx.serialization — JetBrains tomonidan Kotlin obyektlarini JSON, ProtoBuf, CBOR va boshqa formatlarga refleksiyasiz aylantirish uchun koʻp platformali kutubxona. Gson va Moshidan farqli oʻlaroq, u @Serializable annotatsiyasi orqali kompilatsiya bosqichida serializator kodini yaratadi, bu esa yuqori samaradorlik va tip xavfsizligini taʻminlaydi. GitHub Kotlin/kotlinx.serialization maʻlumotlariga koʻra, kutubxona Kotlin/JVM, Kotlin/Native, Kotlin/JS va Kotlin/Wasm-ni qoʻlab-quvvatlaydi.

Asosiy

  • kotlinx.serialization — kompilatsiya vaqtida serializatsiya: kod kompilatsiya bosqichida yaratiladi, refleksiya ishlatilmaydi
  • @Serializable — sinf uchun serializator yaratilishini boshlaydigan asosiy annotatsiya
  • Json {} builder — JSON konfiguratsiyasi: Json { ignoreUnknownKeys = true; prettyPrint = true }
  • Koʻp platformalilik — kutubxona API ni oʻzgartirmasdan JVM, Native, JS va Wasm da ishlaydi
  • Maxsus serializatorlar — nostandart maʻlumot formatlari uchun KSerializer interfeysi orqali

Kotlinx.serialization nima

kotlinx.serialization — JetBrains tomonidan rasmiy Kotlin ekotizimining bir qismi sifatida ishlab chiqilgan Kotlin uchun oʻrnatilgan serializatsiya kutubxonasi. Uning uchinchi tomon echimlaridan (Gson, Moshi, Jackson) asosiy farqi shundaki, u ishlash vaqtida refleksiyadan foydalanmaydi. Buning oʻrniga serializator kodi Kotlin Symbol Processing (KSP) yoki Kotlin Compiler Plugin yordamida kompilatsiya bosqichida yaratiladi. Bu Gson bilan solishtirganda 3-5 baravar samaradorlik oshishini va tip xavfsizligini taʻminlaydi.

Kutubxona rasmiy ravishda toʻrtta formatni qoʻlab-quvvatlaydi: JSON (kotlinx-serialization-json moduli orqali), ProtoBuf (kotlinx-serialization-protobuf), CBOR (kotlinx-serialization-cbor) va HOCON (kotlinx-serialization-hocon). Formatlar build.gradle.kts da alohida bogʻliqliklar sifatida qoʻshiladi, bu esa loyihaga keraksiz kutubxonalarni tortmaslikka imkon beradi. Har bir format uchun oʻz konfiguratsiya parametrlari toʻplami mavjud.

Koʻp platformalilik — kutubxonaning asosiy xususiyati. @Serializable bilan bir xil sinf barcha maqsadli platformalarda ishlaydi: JVM (Android, Backend), Native (iOS), JS (Web, React) va Wasm (WebAssembly). Dasturchi har bir platforma uchun turli xil serializatsiya implementatsiyalarini yozishi shart emas — kod yagona boʻlib qoladi. Bu, ayniqsa, umumiy kod Android va iOS oʻrtasida taqsimlanadigan Kotlin Multiplatform Mobile (KMM) loyihalarida qimmatlidir.

Kompilatsiya vaqtida kod yaratilishi qanday ishlaydi

Kod yaratilishi kotlinx.serialization da uch bosqichda amalga oshiriladi. Birinchi bosqichda Kotlin kompilatori sinfda @Serializable annotatsiyasini aniqlaydi va uni Kotlin Symbol Processing (KSP) plagiga uzatadi. Ikkinchi bosqichda KSP KSerializer interfeysini amalga oshiradigan serializator obyektini yaratadi. Uchinchi bosqichda yaratilgan kod loyihaning manba kodi bilan birga kompilatsiya qilinadi. Natijada, bu bosqichlarning hech biri dastur ishlashi vaqtida bajarilmaydi.

Yaratilgan serializator sinf maydonlari bilan toʻgʻridan-toʻgʻri ularning getter va setterlari orqali, refleksiyasiz ishlaydi. Bu shuni anglatadiki, private modifikatoriga ega maydonlar ham @Serializable bilan belgilangan boʻlsa, serializatsiya qilinadi. Ushbu yondashuvning samaradorligi qoʻlda serializatsiyaga yaqin: oddiy sinflar (5-10 maydon) uchun serializatsiya vaqti 10-50 mikrosekund, murakkab obyekt graflari uchun 1000 obyektga 200 mikrosekundgacha.

Android yoki Kotlin/JVM loyihasida kutubxonani ulash uchun build.gradle.kts fayliga plagin va bogʻliqliklarni qoʻshish kerak. Kotlin versiyasiga mos keladigan org.jetbrains.kotlin.plugin.serialization plagini kod yaratilishini faollashtiradi. kotlinx-serialization-json kutubxonasi dependencies boʻlimida Kotlin versiyasiga bogʻliq boʻlmagan versiya bilan qoʻshiladi.

kotlin
// build.gradle.kts — kotlinx.serialization ulanishi
plugins {
    val kotlinVersion = "2.1.0"
    kotlin("jvm") version kotlinVersion
    kotlin("plugin.serialization") version kotlinVersion
}

dependencies {
    // Asosiy serializatsiya moduli
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")

    // Qoʻshimcha formatlar
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.7.3")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-cbor:1.7.3")
}

Asosiy foydalanish: JSON serializatsiyasi

JSON — kotlinx.serialization da eng mashhur format. Obyektni serializatsiya qilish uchun data class ga @Serializable annotatsiyasini qoʻyish va Json.encodeToString() ni chaqirish kifoya. Deserializatsiya uchun — Json.decodeFromString() turni koʻrsatgan holda. Kutubxona avtomatik ravishda null maydonlarni, roʻyxatlarni, ichki obyektlarni va enumlarni boshqaradi. Sinfning barcha maydonlari boshqacha koʻrsatilmagan boʻlsa, majburiydir.

JSON konfiguratsiyasi Json {} builder orqali amalga oshiriladi. Konstruktorga deserializatsiya vaqtida nomaʻlum maydonlarni oʻtkazib yuborish uchun ignoreUnknownKeys = true, formatlangan chiqish uchun prettyPrint = true, notoʻgʻri qiymatlarni standart qiymatlarga aylantirish uchun coerceInputValues = true berilishi mumkin. Shuningdek, encodeDefaults (standart qiymatli maydonlarni serializatsiya qilish) va classDiscriminator (polimorf serializatsiya uchun maydon nomi) sozlamalari mavjud.

kotlin
// JSON serializatsiyasi va deserializatsiyasi misoli
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration

@Serializable
data class Project(
    val name: String,
    val stars: Int,
    val isActive: Boolean = true,
    val languages: List<String> = emptyList()
)

fun main() {
    val project = Project(
        name = "kotlinx.serialization",
        stars = 7200,
        languages = listOf("Kotlin", "Java")
    )

    // JSON ga prettyPrint bilan serializatsiya
    val json = Json { prettyPrint = true }
    val jsonString = json.encodeToString(project)
    println(jsonString)
    /*
    {
        "name": "kotlinx.serialization",
        "stars": 7200,
        "isActive": true,
        "languages": ["Kotlin", "Java"]
    }
    */

    // JSON dan deserializatsiya
    val decoded = json.decodeFromString<Project>(jsonString)
    println(decoded.name)  // kotlinx.serialization
}

Misol asosiy tsiklni — serializatsiya va deserializatsiyani koʻrsatadi. @Serializable annotatsiyasiga ega Project data class avtomatik ravishda encodeToString va decodeFromString oladi. isActive maydoni standart qiymat true ga ega — agar bu maydon JSON da boʻlmasa, standart qiymat ishlatiladi. Agar ignoreUnknownKeys = true boʻlmagan holda JSON da nomaʻlum maydonlar kelsa, SerializationException istisnosi tashlanadi.

Sealed class polimorf serializatsiyasi

Sealed class — kotlinx.serialization ning eng kuchli foydalanish holatlaridan biri. Kutubxona qoʻshimcha konfiguratsiyasiz sealed class iyerarxiyalari uchun polimorf serializatsiyani qoʻlab-quvvatlaydi: sealed class va uning barcha vorislarini @Serializable bilan belgilash kifoya. Serializatsiya vaqtida „type” maydoni (classDiscriminator orqali sozlanishi mumkin) qoʻshiladi, uning asosida deserializatsiya vaqtida aniq tur aniqlanadi.

kotlin
// Sealed class polimorf serializatsiyasi
@Serializable
sealed class Response

@Serializable
data class Success(val data: String) : Response()

@Serializable
data class Error(val code: Int, val message: String) : Response()

fun main() {
    val json = Json { classDiscriminator = "result_type" }

    val responses: List<Response> = listOf(
        Success(data = "Data loaded"),
        Error(code = 404, message = "Not found")
    )

    val jsonString = json.encodeToString(responses)
    println(jsonString)
    /*
    [
        {"result_type":"Success","data":"Data loaded"},
        {"result_type":"Error","code":404,"message":"Not found"}
    ]
    */

    val decoded = json.decodeFromString<List<Response>>(jsonString)
    when (val first = decoded[0]) {
        is Success -> println("Success: ${first.data}")
        is Error -> println("Error: ${first.code}")
    }
}

Sealed class polimorf serializatsiyasi, ayniqsa, server turli xil javob turlarini qaytaradigan API mijozlarida foydalidir. kotlinx.serialization boʻlmagan holda, diskriminator maydoni boʻyicha when bilan qoʻlda deserializator yozish kerak boʻlardi. Kutubxona bilan bu bitta annotatsiya bilan amalga oshiriladi. classDiscriminator marker maydoni nomini (standart „type”) server kutgan istalgan qiymatga oʻzgartirishga imkon beradi.

Kotlinx.serialization annotatsiyalari: toʻliq sharh

Kutubxona serializatsiyani nozik sozlash uchun annotatsiyalar toʻplamini taqdim etadi. Asosiysi sinf uchun @Serializable. Qoʻshimchalar: JSON da maydon nomini belgilash uchun @SerialName (Kotlin nomidan farq qilsa), maydonni serializatsiyadan chiqarish uchun @Transient, JSON da majburiy boʻlgan maydon uchun @Required, standart qiymatli maydonni majburiy serializatsiya qilish uchun @EncodeDefault.

AnnotatsiyaVazifaMisol
@SerializableSinf uchun serializator yaratilishini faollashtiradi@Serializable data class User
@SerialNameMaydonning formatdagi muqobil nomini belgilaydi@SerialName(“user_name”) val name: String
@TransientMaydonni serializatsiyadan chiqaradi@Transient val cache: MutableMap
@RequiredMaydon deserializatsiya vaqtida JSON da majburiy@Required val id: String
@EncodeDefaultMaydonni hatto standart qiymat bilan ham serializatsiya qiladi@EncodeDefault val type: Type = Type.A
@SerializerSinfga maxsus serializatorni biriktiradi@Serializer(forClass = Date::class)

@SerialName annotatsiyasi maydon nomlari snake_case, Kotlin uslubi esa camelCase boʻlgan API lar bilan ishlashda juda muhimdir. Masalan, server “user_id” yuboradi, Kotlin kodida esa userId ishlatiladi. @SerialName(“user_id”) bu muammoni qoʻshimcha mapperlarsiz hal qiladi. @Transient serverga yuborish shart boʻlmagan maydonlar uchun qulay — masalan, vaqtinchalik hisoblash qiymatlari yoki kesh.

@Required nullable maydonlarga muqobil sifatida

Standart boʻyicha kotlinx.serialization da barcha maydonlar majburiydir. Agar maydon JSON da boʻlmasligi mumkin boʻlsa, uni nullable (String?) qilish yoki standart qiymat belgilash kerak (val name: String = “”). Biroq, maydon Kotlin da nullable emas, lekin API versiyalash tufayli JSON da boʻlmasligi mumkin boʻlgan holatlar mavjud. Bu holda @Required maydon yoʻq boʻlganda SerializationException tashlaydi, standart qiymat esa xatosiz default ni toʻldiradi.

Maxsus serializatorlar: KSerializer va qoʻlda boshqarish

KSerializer — kotlinx.serialization da barcha serializatorlar amalga oshiradigan interfeys. Agar standart kod yaratilishi mos kelmasa (masalan, Date, Bitmap yoki maxsus ikkilik format bilan ishlash uchun), oʻz serializatoringizni yozishingiz mumkin. Buning uchun serialize() va deserialize() metodlarini, shuningdek format sxemasi uchun descriptor — struktura tavsifini taqdim etish kerak.

Maxsus serializatorlar ikki usulda ulanadi: muayyan sinfga ulash uchun @Serializable(with = MySerializer::class) annotatsiyasi orqali yoki Json { serializersModule = ... } orqali global ravishda barcha tur namunalariga ulash. Ikkinchi usul oʻrnatilgan turlar (Date, UUID) uchun afzalroqdir, chunki har bir maydonda annotatsiya yozish shart emas.

kotlin
// java.util.Date uchun maxsus serializator
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

object DateSerializer : KSerializer<Date> {
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)

    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING)

    override fun serialize(encoder: Encoder, value: Date) {
        encoder.encodeString(dateFormat.format(value))
    }

    override fun deserialize(decoder: Decoder): Date {
        return dateFormat.parse(decoder.decodeString())
    }
}

// Maxsus serializatordan foydalanish
@Serializable
data class Event(
    val title: String,
    @Serializable(with = DateSerializer::class)
    val date: Date
)

fun main() {
    val json = Json { prettyPrint = true }
    val event = Event("Chiqarilish", Date())
    println(json.encodeToString(event))
}

Misolda DateSerializer java.util.Date ni ISO 8601 qatoriga aylantiradi. Maxsus serializatorsiz kotlinx.serialization Date bilan ishlay olmaydi — bu Kotlin standart kutubxonasiga kirmaydigan turdir. Muayyan maydonda @Serializable(with = DateSerializer::class) serializatorni faqat shu maydon uchun ulaydi. Barcha Date larning global roʻyxatga olinishi uchun Json { serializersModule = SerializersModule { contextual(DateSerializer) } } dan foydalaning.

Serializatsiya formatlari: JSON, ProtoBuf, CBOR, HOCON

kotlinx.serialization faqat JSON bilan cheklanmaydi. Kutubxona toʻrtta oʻrnatilgan formatni qoʻlab-quvvatlaydi, har biri oʻz moduli va konfiguratsiyasiga ega. JSON (kotlinx-serialization-json) — universal, inson oʻqiy oladigan, REST API uchun mos. ProtoBuf (kotlinx-serialization-protobuf) — ikkilik, ixcham, majburiy sxema bilan, yuqori yuklangan mikroxizmatlar uchun. CBOR (kotlinx-serialization-cbor) — JSON ning ikkilik analogi, cheklangan trafikli IoT va mobil qurilmalar uchun qulay. HOCON (kotlinx-serialization-hocon) — TypeSafe Config bilan mos keladigan konfiguratsiya formati.

FormatModulTurSxemaOdatiy qoʻllanish
JSONkotlinx-serialization-jsonMatnliIxtiyoriyREST API, maʻlumot saqlash
ProtoBufkotlinx-serialization-protobufIkkilikMajburiy (.proto)Mikroxizmatlar, gRPC
CBORkotlinx-serialization-cborIkkilikIxtiyoriyIoT, mobil qurilmalar
HOCONkotlinx-serialization-hoconMatnliIxtiyoriyKonfiguratsiya fayllari

ProtoBuf .proto fayllarida sxema belgilashni talab qiladi, lekin kotlinx-serialization-protobuf Kotlin sinflarini toʻgʻridan-toʻgʻri @Serializable dan .proto siz yaratadi. Bu rivojlanishni soddalashtiradi: data class ni annotatsiya qilish va ProtoBuf.encodeToByteArray() dan foydalanish kifoya. CBOR, ayniqsa, NFC yoki BLE orqali ixcham ikkilik maʻlumotlarni uzatish kerak boʻlganda Android ramkasi uchun dolzarbdir. CBOR xabarining hajmi bir xil maʻlumotlar toʻplami bilan JSON dan oʻrta hisobda 20-30% kichikroq.

Loyiha uchun format tanlash

Mobil ilovada REST API uchun JSON maqbuldir — qoʻshimcha vositalarsiz sozlanadi, jurnallarda oʻqiladi va har qanday backend bilan mos keladi. Agar ilova mikroxizmatlar oʻrtasida katta hajmdagi maʻlumotlarni uzatsa (yuzlab megabayt) — ProtoBuf ikkilik kodlash tufayli tezlikni 5 baravargacha oshiradi. Sozlamalarni fayllarda saqlash uchun HOCON yoki JSON dan foydalaning. Qattiq trafik cheklovlari boʻlgan qurilmalar (IoT sensorlari) uchun — CBOR.

Kotlinx.serialization bilan ishlashda odatiy xatolar

Birinchi xato — deserializatsiya vaqtida nomaʻlum kalitlarni eʻtiborsiz qoldirish. Agar server yangi maydon qoʻshgan boʻlsa va ignoreUnknownKeys = false boʻlsa, dastur SerializationException bilan ishdan chiqadi. Standart boʻyicha bu bayroq oʻchirilgan. Yechim: API oʻzgarishlariga chidamli boʻlish uchun ishlab chiqarish kodida har doim Json { ignoreUnknownKeys = true } ni oʻrnating.

Ikkinchi xato — data class da internal yoki private maydonlarni serializatsiya qilish. Kotlin data class da primary konstruktordagi barcha maydonlar standart boʻyicha serializatsiya qilinadi. Agar maydon maxfiy maʻlumotlarni oʻz ichiga olsa (parol, token), uni @Transient bilan belgilash yoki primary konstruktordan chiqarish kerak. @Transient maydonni JSON dan butunlay chiqarib tashlaydi, lekin konstruktorda xatoga olib kelishi mumkin — bunday maydonni @Transient bilan sinf tanasida belgilash yaxshiroqdir.

Uchinchi xato — sealed class siz polimorf serializatsiya. Agar sealed oʻrniga open class ishlatilsa, kotlinx.serialization serializersModule da barcha vorislarning aniq roʻyxatga olinishini talab qiladi. sealed class dan farqli oʻlaroq, kompilator barcha vorislarni biladi, open class esa ixtiyoriy kengaytirishga imkon beradi — kutubxona barcha pastki turlarni avtomatik aniqlay olmaydi. Roʻyxatga olish Json { serializersModule = SerializersModule { polymorphic(Base::class) { subclass(Derived::class) } } } orqali amalga oshiriladi.

Kutubxona versiyalash xatosi

kotlinx.serialization versiyasi Kotlin versiyasiga mos boʻlishi kerak. JetBrains moslik jadvalini eʻlon qiladi: kotlinx-serialization 1.6.x Kotlin 1.9.x bilan, 1.7.x Kotlin 2.0.x va 2.1.x bilan mos keladi. Versiyalarning mos kelmasligi „Symbol ‘serializer’ is missing” kabi tushunarsiz kompilatsiya xatolariga sabab boʻladi. Har doim joriy versiyani mavenCentral da yoki loyihaning GitHub repozitoriyasida tekshiring.

Tez-tez beriladigan savollar

Kotlinx.serialization Gson va Moshidan qanday farq qiladi?

kotlinx.serialization KSP orqali kompilatsiya vaqtida kod yaratishdan foydalanadi, Gson va Moshi esa ishlash vaqtida refleksiyadan foydalanadi. Bu samaradorlikda ustunlik (Gson dan 3-5 baravar tez) va tip xavfsizligini taʻminlaydi. Gson annotatsiyasiz istalgan maydonni serializatsiya qiladi, bu maʻlumot sizib chiqishiga olib kelishi mumkin. kotlinx.serialization aniq @Serializable annotatsiyasini talab qiladi, bu xavfsizroqdir. Moshi ham codegen ni qoʻlab-quvvatlaydi, lekin faqat JVM va Android uchun.

Kotlinx.serialization Kotlin Multiplatform ni qoʻlab-quvvatlaydimi?

Ha, kotlinx.serialization JetBrainsning rasmiy koʻp platformali kutubxonasi. U Kotlin/JVM (Android, Backend), Kotlin/Native (iOS), Kotlin/JS (Web, React) va Kotlin/Wasm da ishlaydi. API barcha platformalar uchun yagonadir: @Serializable + Json.encodeToString() hamma joyda bir xil ishlaydi. iOS uchun qoʻshimcha sozlamalar talab qilinmaydi — Kotlin/Native serializatsiya qilingan kodni mahalliy ikkilik faylga kompilatsiya qiladi.

JSON da null maydonlarni qanday boshqarish kerak?

Nullable maydonlar (String?) JSON da qiymat boʻlmasa yoki null koʻrsatilsa, null sifatida deserializatsiya qilinadi. Standart qiymati boʻlmagan non-nullable maydonlar (String) uchun JSON da maydonning yoʻqligi SerializationException ga sabab boʻladi. Agar null qiymatlarning JSON ga tushishini istamasangiz, Json { encodeDefaults = false } ni sozlang. Bu default ga teng boʻlgan barcha maydonlarni (nullable uchun null ni oʻz ichiga olgan holda) chiqishdan chiqaradi.

Agar server snake_case maydonlarini yuborsa nima qilish kerak?

@SerialName(“snake_case_name”) dan foydalaning nomi Kotlin formatidan farq qiladigan har bir maydonda. Shu bilan birga, Kotlin 2.0+ uchun Json { namingStrategy = JsonNamingStrategy.SnakeCase } mavjud — camelCase ↔ snake_case avtomatik konversiyasi. Bu sozlama barcha maydonlarga bir vaqtning oʻzida qoʻllaniladi. Qisman moslashtirish kerak boʻlsa, @SerialName ni global strategiya bilan birlashtiring.

Kotlin Flow yoki korutinlarni serializatsiya qilish mumkinmi?

Yoʻq, Flow va korutinlar toʻgʻridan-toʻgʻri serializatsiya qilinmaydi — ular asinxron bajarilishni ifodalaydi, maʻlumotni emas. Flow dan maʻlumot uzatish uchun uni korutinda .toList() orqali toʻplamga yigʻish va toʻplamni serializatsiya qilish kerak. Xuddi shunday, Job, Deferred yoki Continuation ni serializatsiya qilib boʻlmaydi. Faqat data class — xatti-harakat mantigʻi boʻlmagan maʻlumot modellarini serializatsiya qiling.

Xulosalar

  • kotlinx.serialization — @Serializable orqali kompilatsiya vaqtida serializatsiya, refleksiyasiz, Gson dan 5 baravargacha yuqori samaradorlik
  • @Serializable, @SerialName, @Transient — maydon va sinf serializatsiyasini sozlash uchun asosiy annotatsiyalar
  • Json {} builder JSON ni sozlaydi: ignoreUnknownKeys, prettyPrint, coerceInputValues, encodeDefaults
  • Sealed class va polimorf serializatsiya — qoʻshimcha kodsiz tur iyerarxiyalarini muammosiz qoʻlab-quvvatlash
  • KSerializer — nostandart turlar (Date, Bitmap, UUID) uchun maxsus serializatorlar interfeysi
  • Toʻrt format: JSON, ProtoBuf, CBOR, HOCON — modullar bilan ulanadi, API barcha uchun yagona
  • Koʻp platformalilik — JVM, Native, JS va Wasm uchun yagona kod; KMM va umumiy modullar uchun muhim

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing