In Kotlin, il modificatore const val viene utilizzato solo per le costanti a tempo di compilazione a livello top-level (a livello di file), o all'interno di oggetti (object) e oggetti companion. Le proprietà dichiarate come val all'interno delle classi diventano normali proprietà final senza inizializzazione statica. Un'importante caratteristica: const val non può essere ereditato, mentre val può essere sovrascritto (se consentito).
Le costanti (const val) non possono essere astratte, poiché devono avere un valore al momento della compilazione. Le normali val consentono di implementare un pattern di costante nelle gerarchie attraverso proprietà aperte, tuttavia a runtime saranno accessibili tramite un getter, cosa che differisce dalla compilazione in Java.
open class Base { open val info: String = "base" } class Child : Base() { override val info = "child" } object Constants { const val APPLICATION_NAME = "MyApp" }
È possibile dichiarare
const valin un'interfaccia o in una classe astratta e poi sovrascriverlo/ereditarlo?
No. In Kotlin non è possibile dichiarare const val all'interno di un'interfaccia o di una classe astratta — questo è consentito solo a livello di oggetto (object) e top-level. Non ci sono variabili static final analoghe accessibili per ereditarietà.
interface Foo { // const val X = "constant" // errore di compilazione: 'val' const sono consentiti solo a livello top-level, negli oggetti o negli oggetti companion }
Storia
Il team ha cercato di riutilizzare costanti stringa tramite l'ereditarietà dell'interfaccia in diversi moduli Android, dichiarandole come
const val— hanno ricevuto un errore di compilazione e sono stati costretti a spostare le costanti a livello top-level, il che ha peggiorato l'incapsulamento.
Storia
Nel progetto, hanno convertito tutti i campi static final di Java in campi
valdi Kotlin in classi aperte, aspettandosi lo stesso comportamento (costante a tempo di compilazione), ma sono diventati normali proprietà con getter. Di conseguenza, il tempo di accesso è aumentato, il che ha avuto un impatto negativo sui percorsi caldi (hot path) dell'applicazione microservizi.
Storia
Durante il porting delle classi Java contenitori di costanti in Kotlin, gli sviluppatori hanno creato costanti all'interno dell'oggetto companion, ma si sono trovati di fronte a un problema di accesso dal codice Java: le costanti erano visibili come campi dell'oggetto companion stesso, e non della classe, causando confusione nell'API e bug aggiuntivi di interoperabilità.