JSON serialization: Gson, Moshi, kotlinx.serialization
Üç əsas kitabxananın fərqi null-safety və Kotlin dəstəyindədir:
- Gson — ən köhnə, reflection əsaslı. Kotlin-in null-safety-sindən xəbərsizdir: non-null
Stringsahəsinə null yaza bilir → NPE sonra, gözlənilməz yerdə partlayır. Default dəyərlər reflection yolu ilə itir. - Moshi — Square-in müasir kitabxanası: codegen rejimində (
@JsonClass(generateAdapter = true)) Kotlin null-safety-yə hörmət edir — null gələndə parse anında aydın exception. Reflection rejimi də var. - kotlinx.serialization — JetBrains-in compiler plugin həlli:
@Serializableannotasiyası, reflection sıfır, multiplatform, default dəyərlər tam işləyir. Retrofit üçün rəsmi converter var.
Müsahibə sualının nüvəsi: "API null qaytarsa nə olur?" Gson — səssiz null non-null sahədə (gizli bomba); Moshi codegen / kotlinx — parse xətası dərhal (fail fast). Bank tətbiqində fail-fast üstündür: korrupt data ilə davam etməkdən yaxşıdır.
// Gson — annotasiya yalnız ad uyğunluğu üçün
data class TxDto(
@SerializedName("tx_id") val txId: String, // Gson null yaza bilər!
@SerializedName("amount") val amount: Long = 0 // default itir
)
// Moshi codegen — null gələrsə JsonDataException
@JsonClass(generateAdapter = true)
data class TxDto(
@Json(name = "tx_id") val txId: String,
@Json(name = "amount") val amount: Long = 0 // default işləyir
)
// kotlinx.serialization
@Serializable
data class TxDto(
@SerialName("tx_id") val txId: String,
@SerialName("amount") val amount: Long = 0 // default işləyir
)Eyni DTO üç kitabxanada
Proguard/R8 tələsi: reflection əsaslı serialization (Gson, Moshi reflection) obfuscation-dan sonra sahə adlarını itirir — release build-də parse sınır, debug-da işləyir. Həll: DTO-lara @Keep/keep qaydaları, ya da codegen rejimlərinə keçid (onlara qayda lazım deyil). "Debug işləyir, release-də sınır" simptomunu eşidəndə ilk şübhələnəcəyin yer budur.
🛠 Tapşırıq
Null bombasını öz gözünlə gör: data class UserDto(val name: String) yaz və {"name": null} JSON-unu Gson ilə parse et.
- Exception atılmadığını, sonra
name.lengthçağırışında NPE gəldiyini təsdiqlə. - Eyni JSON-u Moshi codegen və ya kotlinx.serialization ilə parse et — xətanın harada çıxdığını müqayisə et.
- Pul sahəsini
Doublekimi parse edib0.1 + 0.2-ni çap et; sonraLong(qəpik) vəBigDecimalvariantını yaz.
Bitdi sayılır: "pulu niyə Double saxlamırıq" sualına konkret çıxışla cavab verirsənsə.
📚 Mənbələr və sənədlər
- kotlinx.serialization — Kotlin sənədlərirəsmikotlinlang.org
- Moshirəsmigithub.com
- Gsonrəsmigithub.com