programowanieProgramista Kotlin

Opisz mechanizm klas enum w Kotlinie: co to jest klasa enum, czym różni się od Javy, jakie ma cechy i ograniczenia, jak dodawać własną funkcjonalność, jakie mogą wystąpić problemy przy serializacji i porównywaniu. Podaj przykład.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

W Kotlinie enumeracje (enum class) umożliwiają zadeklarowanie zbioru ograniczonych wartości, przy jednoczesnym rozszerzeniu ich metodami i właściwościami.

Podstawowe punkty:

  • Klasa enum jest deklarowana podobnie jak w Javie, ale składnia jest bardziej rygorystyczna:
    enum class Direction { NORTH, SOUTH, WEST, EAST }
  • Elementy enum to singletony, instancje odpowiedniego podtypu klasy.
  • Można definiować dodatkowe właściwości i metody wewnątrz enum:
    enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF); fun containsRed() = (rgb and 0xFF0000 != 0) }
  • Do każdego wartości można uzyskać dostęp po nazwie (Color.RED.name), indeksie (ordinal) i uzyskiwać pełną listę za pomocą values().
  • W Kotlinie nie można dziedziczyć po klasach enum, ale można implementować interfejsy.
  • Różnica z Javą — nie można jawnie dziedziczyć klas od enum, nie można używać zagnieżdżonych list;
  • Enum w Kotlinie nie jest domyślnie serializowany za pomocą standardowych narzędzi (np. Gson lub Jackson) — potrzebne są specjalne adaptery/annotacje.

Porównanie enum:

  • Enumy są porównywane przez == (tożsamość), ponieważ elementy są unikalne.
  • Przy serializacji nazwy mogą się zmieniać, lepiej jawnie podawać wartości (wzorzec wartości przechowywania).

Pytanie z pułapką.

Czy można zdefiniować metodę abstrakcyjną wewnątrz klasy enum w Kotlinie, tak jak w Javie, aby każdy element ją nadpisywał?

Prawidłowa odpowiedź: Tak, można zadeklarować metodę abstrakcyjną w stylu enum, a każdy element musi dostarczyć swoją implementację!

enum class State { START { override fun next() = RUNNING }, RUNNING { override fun next() = STOPPED }, STOPPED { override fun next() = STOPPED }; abstract fun next(): State }

Przykłady rzeczywistych błędów z powodu nieznajomości subtelności tematu.


Historia

Przy migracji z Javy do Kotlinu zespół próbował dziedziczyć nową klasę enum jak zwykłą klasę — okazało się, że klasy enum nie można dziedziczyć, co naruszyło architekturę. Trzeba było całkowicie zmienić podejście do modularności maszyn stanowych.


Historia

Do przechowywania wartości w bazie danych brano nazwę elementu (enum.name), ale przy refaktoryzacji enum zmieniono nazwy elementów — dane z bazy przestały odpowiadać nowej logice, nastąpiła utrata spójności (wzorzec wartości przechowywania nie został wdrożony).


Historia

Przy serializacji klasy enum przez Gson zapomniano podłączyć niestandardowy TypeAdapter. W produkcji usługa zaczęła zwracać nieprawidłowe wartości JSON, ponieważ standardowy parser serializował niewłaściwe pole (ordinal lub name), a deserializacja nie zgadzała się między mikroserwisami.