Как используется рефлексия при сериализации
Что проверяют
Понимаете ли вы, какие библиотеки сериализации на Android ходят в поля через рефлексию, а какие генерируют код на этапе сборки, и чем это оборачивается в релизной сборке. Типичный уточняющий вопрос: почему после включения R8 JSON вдруг стал приходить с пустыми полями.
Как отвечать
Механика простая: библиотека берёт класс объекта, перебирает getDeclaredFields(), снимает защиту через setAccessible(true) и читает или записывает значения по имени поля. Где это встречается:
java.io.Serializable:ObjectOutputStreamрефлексией обходит поля, учитываетtransientиserialVersionUID. На Android медленно и для передачи данных почти не используется;- Gson: чисто рефлексивный. Объект создаёт через
Unsafe, минуя конструктор, поэтому в Kotlin значения по умолчанию не применяются, а non-null поле может оказатьсяnull. Сами авторы держат Gson в режиме поддержки; - Moshi: два режима.
KotlinJsonAdapterFactoryработает черезkotlin-reflect, а@JsonClass(generateAdapter = true)с KSP генерирует адаптеры без рефлексии; - kotlinx.serialization: плагин компилятора генерирует сериализаторы для
@Serializable, рефлексии в рантайме нет, работает и в Kotlin Multiplatform; Parcelable: запись вParcelпишется руками или генерируется@Parcelize, поэтому он быстрееSerializableпри передаче черезIntentиBundle.
Цена рефлексии на мобильном устройстве: медленный первый разбор, особенно на холодном старте, лишний размер от kotlin-reflect и хрупкость при обфускации. Поэтому в новых проектах выбирают генерацию кода.
Где спотыкаются
Забывают про R8. Он переименовывает поля, и Gson сериализует a и b вместо name и price. Нужны @SerializedName или keep-правила для моделей.
Не знают, что Gson обходит конструктор. Kotlin обещает non-null, а в рантайме вылетает NullPointerException совсем в другом месте.
Говорят, что рефлексия нужна для любой сериализации. Kotlinx.serialization и кодогенерация Moshi показывают обратное, и на Android именно они стали стандартом.