ProgrammazioneSviluppatore Kotlin

Descrivi il meccanismo delle enum class in Kotlin: cosa sono le enum class, quali sono le differenze rispetto a Java, quali sono le caratteristiche e le limitazioni delle enum, come aggiungere funzionalità proprie, quali sono le sfide che possono insorgere durante la serializzazione e il confronto. Fornisci un esempio.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In Kotlin, le enumerazioni (enum class) consentono di dichiarare un insieme di valori limitati e allo stesso tempo di espanderli con metodi e proprietà.

Punti principali:

  • L'enum class viene dichiarata in modo simile a Java, ma la sintassi è più rigorosa:
    enum class Direction { NORTH, SOUTH, WEST, EAST }
  • Gli elementi delle enum sono singleton, istanze del rispettivo sottotipo di classe.
  • È possibile definire proprietà e metodi aggiuntivi all'interno dell'enum:
    enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF); fun containsRed() = (rgb and 0xFF0000 != 0) }
  • Ogni valore può essere accessibile per nome (Color.RED.name), indice (ordinal) e ottenere un elenco completo tramite values().
  • In Kotlin non è possibile estendere le enum class, ma è possibile implementare interfacce.
  • La differenza rispetto a Java è che non è possibile ereditare esplicitamente le classi dalle enum, non è possibile utilizzare una lista nidificata;
  • Le enum in Kotlin non vengono serializzate per impostazione predefinita tramite strumenti standard (ad esempio, Gson o Jackson) - sono necessari adattatori/annotazioni speciali.

Confronto delle enum:

  • Le enum vengono confrontate tramite == (identità), poiché gli elementi sono unici.
  • Durante la serializzazione, i nomi possono cambiare, è meglio specificare esplicitamente i valori (storage value pattern).

Domanda trabocchetto.

È possibile definire un metodo astratto all'interno di un'enum class in Kotlin, come in Java, in modo che ogni elemento lo sovrascriva?

Risposta corretta: Sì, è possibile dichiarare un metodo astratto nello stile enum, e ogni elemento deve fornire la propria implementazione!

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

Esempi di errori reali causati dalla mancanza di conoscenza delle sottigliezze dell'argomento.


Storia

Durante la migrazione da Java a Kotlin, il team ha tentato di ereditare una nuova enum class come una normale classe - si è scoperto che le enum non possono essere ereditate, compromettendo l'architettura. È stato necessario cambiare completamente l'approccio alla modularità delle macchine a stati.


Storia

Per memorizzare il valore nel database si utilizzava il nome dell'elemento (enum.name), ma con il refactoring le enum sono state rinominate - i dati nel database hanno smesso di corrispondere alla nuova logica, c'è stata una perdita di coerenza (lo storage value pattern non è stato implementato).


Storia

Per serializzare un'enum class tramite Gson, è stato dimenticato di collegare il TypeAdapter personalizzato. In produzione, il servizio ha iniziato a restituire valori JSON errati, poiché il parser standard serializzava il campo sbagliato (ordinal o name), e la deserializzazione non corrispondeva tra i microservizi.