Gson — что это такое, библиотека JSON для Java и Kotlin

Автор: IT Sectr Опубликовано: 2026-03-15 Время чтения: 8 мин

Gson — библиотека от Google для сериализации Java-объектов в JSON и обратно, широко используемая в Android-разработке. Она позволяет преобразовывать сложные графы объектов в компактные JSON-строки без ручного написания парсеров. По данным Google Gson, 2024, библиотека насчитывает более 23 тысяч звёзд на GitHub и остаётся одним из самых популярных решений для работы с JSON в экосистеме Java и Kotlin.

Главное

  • Gson — библиотека Google для JSON-сериализации в Java и Kotlin
  • fromJson — десериализация JSON в Java-объект любого типа
  • toJson — сериализация объекта в JSON-строку
  • @SerializedName — аннотация для привязки JSON-ключа к полю класса
  • TypeToken — работа с дженериками и параметризованными типами

Что такое Gson

Gson — это Java-библиотека, разработанная Google для преобразования объектов в JSON-представление и обратно. Она использует рефлексию для анализа структуры классов, что позволяет работать без предварительной конфигурации. Gson поддерживает произвольные Java-объекты, коллекции, массивы, дженерики и вложенные классы. Библиотека не требует аннотаций для базового использования, но предоставляет их для тонкой настройки. Основной недостаток рефлексии — снижение производительности при инициализации и невозможность оптимизации на этапе компиляции, что особенно заметно на холодном старте Android-приложения при десериализации сотен моделей. Несмотря на это, Gson остаётся надёжным выбором для большинства проектов благодаря стабильности и обширной документации.

История и место в экосистеме

Gson был выпущен Google в 2008 году и быстро стал стандартом де-факто для JSON в Android-приложениях. До появления Moshi и kotlinx.serialization Gson оставался единственным популярным выбором для Kotlin-проектов. Простота подключения — добавление одной зависимости в build.gradle — и отсутствие обязательных аннотаций сделали Gson популярным среди разработчиков любого уровня.

groovy
// Подключение Gson в build.gradle
dependencies {
    implementation 'com.google.code.gson:gson:2.10.1'
}

// Базовое использование
data class User(
    val id: Int,
    val name: String,
    val email: String
)

val gson = Gson()
val user = User(1, "John", "john@test.com")
val json = gson.toJson(user)
println(json) // {"id":1,"name":"John","email":"john@test.com"}

Помимо базовой сериализации, Gson предоставляет GsonBuilder для настройки поведения: форматирование дат, отключение экранирования HTML, регистр ключей и пользовательские экземпляры. GsonBuilder также позволяет регистрировать кастомные JsonSerializer и JsonDeserializer для типов, которые библиотека не может обработать автоматически. Гибкость конфигурации делает GsonBuilder незаменимым и полезным инструментом при адаптации библиотеки под специфические требования проекта в современной Android-разработке.

Основные операции toJson и fromJson

toJson преобразует Java-объект в JSON-строку, анализируя его поля через рефлексию. По умолчанию Gson включает все поля, кроме transient и static. Метод поддерживает любые типы: примитивы, объекты, коллекции и массивы. fromJson выполняет обратное преобразование, принимая JSON-строку и класс целевого объекта, и возвращает экземпляр с заполненными полями.

Преобразование объекта в JSON

При сериализации Gson рекурсивно обходит все поля объекта, включая вложенные. Циклические ссылки приводят к StackOverflowError, поэтому их нужно исключать через аннотацию @Expose или кастомный адаптер. Для коллекций Gson сохраняет тип элементов, но при десериализации списка с дженериками требуется TypeToken для сохранения информации о типе.

kotlin
// data class с вложенным объектом
data class Address(
    val city: String,
    val street: String
)

data class Employee(
    val id: Int,
    val name: String,
    val address: Address
)

val gson = Gson()
val employee = Employee(1, "Alice",
    Address("New York", "5th Ave"))

// Сериализация в JSON
val json = gson.toJson(employee)

// Десериализация из JSON
val jsonString = """
{"id":2,"name":"Bob","address":{"city":"London","street":"Baker St"}}
"""
val parsed = gson.fromJson(jsonString, Employee::class.java)

Аннотации и настройка

Gson предоставляет набор аннотаций для управления процессом сериализации. @SerializedName задаёт имя JSON-ключа, отличающееся от имени поля. @Expose управляет включением поля в сериализацию: Gson, созданный через GsonBuilder.excludeFieldsWithoutExposeAnnotation(), будет обрабатывать только поля с @Expose. @Since и @Until контролируют версионность полей.

@SerializedName и @Expose

Аннотация @SerializedName решает проблему несоответствия имён: сервер может использовать snake_case, а в коде принят camelCase. Аннотация принимает значение и опциональные альтернативы для обратной совместимости. @Expose позволяет скрыть чувствительные поля (пароли, токены) от сериализации, помечая их как @Expose(serialize = false). Помимо включения и исключения, @Expose можно комбинировать с GsonBuilder.excludeFieldsWithoutExposeAnnotation для создания белого списка полей, что помогает контролировать поверхность атаки при сериализации объектов с большим количеством полей.

kotlin
// Модель с аннотациями Gson
data class UserResponse(
    @SerializedName("user_id")
    val userId: Int,

    @SerializedName("full_name",
        alternate = [Alternative("name")])
    val fullName: String,

    @Expose(serialize = false)
    val password: String
)

// Gson с фильтрацией @Expose
val gson = GsonBuilder()
    .excludeFieldsWithoutExposeAnnotation()
    .setPrettyPrinting()
    .create()

val user = UserResponse(1, "John", "secret123")
println(gson.toJson(user))
// {"user_id":1,"full_name":"John"} — password excluded

Работа с дженериками

Проблема дженериков в Java и Kotlin заключается в стирании типов во время компиляции. Когда Gson десериализует List<User>, он не знает тип элемента и возвращает List<Map<String, Any>>. Для сохранения информации о типе Gson предоставляет TypeToken — абстрактный класс, который захватывает параметр типа через анонимный класс. Без TypeToken разработчику пришлось бы вручную преобразовывать каждый элемент из Map в целевой тип, что приводит к громоздкому коду и потере производительности.

TypeToken для списков

TypeToken решает проблему стирания типов. Разработчик создаёт анонимный наследник TypeToken с нужным параметром типа, и Gson использует информацию из сигнатуры класса для корректной десериализации. TypeToken также работает с Map, Set и любыми другими параметризованными типами, включая вложенные дженерики. В частности, для Map<String, List<User>> требуется TypeToken с полной сигнатурой вложенного типа, иначе Gson десериализует значения как List<Map<String, Any>> вместо List<User>.

kotlin
// TypeToken для десериализации списка
data class Product(
    val id: Int,
    val title: String,
    val price: Double
)

val jsonArray = """
[
    {"id":1,"title":"Phone","price":599.0},
    {"id":2,"title":"Laptop","price":1299.0}
]
"""

val gson = Gson()
val listType = object : TypeToken<List<Product>>() {}
val products: List<Product> =
    gson.fromJson(jsonArray, listType.type)

// Кастомный десериализатор
class LocalDateAdapter :
    JsonDeserializer<LocalDate> {

    override fun deserialize(
        json: JsonElement,
        typeOfT: java.lang.reflect.Type,
        context: JsonDeserializationContext
    ): LocalDate {
        return LocalDate.parse(json.asString)
    }
}

Для кастомной логики сериализации Gson поддерживает интерфейсы JsonSerializer и JsonDeserializer. Они регистрируются через GsonBuilder.registerTypeAdapter() и позволяют обрабатывать типы, которые библиотека не может сериализовать автоматически: даты Java 8, Enum с нестандартными значениями или сторонние классы без доступа к исходному коду. При реализации адаптера важно следить за производительностью: вызов рефлексии внутри кастомного адаптера сводит на нет преимущества ручного управления, поэтому предпочтительно использовать прямые вызовы методов и полей. В экосистеме Gson также существует модуль gson-extras, предоставляющий адаптеры для распространённых типов вроде UUID, Optional и колёс дат Joda-Time.

Настройка через GsonBuilder

GsonBuilder предоставляет десятки методов для тонкой конфигурации сериализации. setPrettyPrinting добавляет отступы и переносы строк в выходной JSON для читаемости. disableHtmlEscaping отключает экранирование символов HTML в строках. setDateFormat задаёт формат дат, что критично при работе с серверами, использующими нестандартное представление времени. setLenient включает ослабленный режим парсинга, который игнорирует некоторые ошибки форматирования JSON. addDeserializationExclusionStrategy позволяет программно исключать поля из десериализации на основе кастомных стратегий. Для отладки полезен метод setPrettyPrinting в сочетании с логированием — он делает JSON-ответы читаемыми в логах и упрощает поиск несоответствий.

Важная возможность GsonBuilder — управление версионностью полей через аннотации @Since и @Until. Разработчик указывает версию объекта через setVersion, и Gson автоматически включает или исключает поля в зависимости от их версионной аннотации. Это полезно при эволюции API, когда одна и та же модель используется для разных версий серверного протокола. GsonBuilder также поддерживает регистрацию TypeAdapterFactory для глобальной обработки семейств типов и complexMapKeySerialization для корректной работы со сложными ключами Map.

Часто задаваемые вопросы

Что такое Gson в разработке Android?

Gson — это библиотека Google для преобразования Java-объектов в JSON и обратно. Она широко используется в Android-приложениях для парсинга ответов сервера, сериализации запросов и сохранения данных в локальном хранилище.

Как Gson обрабатывает null-значения?

По умолчанию Gson пропускает поля с null при сериализации. Для включения null-значений используйте GsonBuilder.serializeNulls(). При десериализации отсутствующие в JSON поля остаются null или принимают значение по умолчанию для типа.

Чем Gson отличается от Moshi?

Moshi не использует рефлексию для Kotlin-классов, что даёт более высокую производительность и предсказуемое поведение. Moshi также корректно обрабатывает null-безопасность Kotlin, в то время как Gson может десериализовать null в non-null поле, вызывая исключение.

Как работает @SerializedName в Gson?

@SerializedName связывает JSON-ключ с полем класса, когда их имена не совпадают. Например, для поля kotlinName и JSON-ключа "kotlin_name" аннотация @SerializedName("kotlin_name") обеспечивает корректное преобразование.

Что такое TypeToken в Gson?

TypeToken — это абстрактный класс, который захватывает параметр типа через анонимный класс. Он необходим для десериализации коллекций и других параметризованных типов, так как из-за стирания типов Gson не может восстановить тип элемента во время выполнения.

Итоги

  • Gson — библиотека Google для JSON-сериализации с поддержкой Java и Kotlin
  • toJson и fromJson — основные методы для сериализации и десериализации объектов
  • @SerializedName — аннотация для сопоставления полей с JSON-ключами при несовпадении имён
  • @Expose — управление видимостью полей при сериализации через GsonBuilder
  • TypeToken — решение проблемы стирания типов для параметризованных коллекций
  • GsonBuilder — конфигурация форматирования, версионности, дат и кастомных адаптеров
  • JsonSerializer/JsonDeserializer — интерфейсы для обработки типов с нестандартной логикой

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также