Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗jvSpJsSf 147 of 322 menu
◀ ▶

Несколько форм в Java

Одно поле может хранить разные варианты данных: успех с числом или ошибка с текстом. Ключевое слово sealed на интерфейсе перечисляет допустимые формы через permits, а Jackson по аннотациям выбирает конкретный record при чтении.

Для JSON на базовый тип вешают @JsonTypeInfo и список @JsonSubTypes. Служебный ключ type становится дискриминатором, короткое имя варианта задают в атрибуте name:

import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = Paid.class, name = "paid"), @JsonSubTypes.Type(value = Declined.class, name = "declined") }) public sealed interface PayReply permits Paid, Declined {} public record Paid(int amount) implements PayReply {} public record Declined(String reason) implements PayReply {}

Запись значения типа PayReply включает "type":"paid" или "type":"declined" рядом с полями варианта:

import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.ObjectMapper; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = Paid.class, name = "paid"), @JsonSubTypes.Type(value = Declined.class, name = "declined") }) public sealed interface PayReply permits Paid, Declined {} public record Paid(int amount) implements PayReply {} public record Declined(String reason) implements PayReply {} public class Main { public static void main(String[] args) throws Exception { PayReply ok = new Paid(900); ObjectMapper mapper = new ObjectMapper(); String text = mapper.writeValueAsString(ok); System.out.println(text); PayReply back = mapper.readValue(text, PayReply.class); System.out.println(back); } }

После разбора статический тип снова PayReply, а фактическая форма определяется при проверке ветки switch с шаблонами. Без коротких имён в @JsonSubTypes в текст попали бы полные имена классов, а не метки протокола.

Опишите sealed интерфейс InboxEvent с вариантами Opened (поле msgId, имя "opened") и Archived (поле folder, имя "archived"). Запишите событие Opened с идентификатором 7 в JSON и выведите строку.

Дана строка JSON:

String raw = "{\"type\":\"archived\",\"folder\":\"2024\"}";

Разберите эту строку в InboxEvent и выведите имя папки из восстановленного варианта.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить