W Kotlin modyfikator const val jest używany tylko dla stałych na etapie kompilacji w top-level (na poziomie pliku), lub wewnątrz obiektów (object) i obiektów towarzyszących. Właściwości zadeklarowane jako val w klasach stają się zwykłymi właściwościami final bez statycznej inicjalizacji. Ważna cecha: const val nie może być dziedziczone, a val można przesłonić (jeśli to dozwolone).
Stałe (const val) nie mogą być abstrakcyjne, ponieważ muszą mieć wartość na etapie kompilacji. Zwykłe val pozwalają wdrożyć wzorzec stałych w hierarchiach poprzez otwarte właściwości, jednak w czasie wykonania będą dostępne przez getter, co różni się od kompilacji w Javie.
open class Base { open val info: String = "base" } class Child : Base() { override val info = "child" } object Constants { const val APPLICATION_NAME = "MyApp" }
Czy można zadeklarować
const valw interfejsie lub klasie abstrakcyjnej, a następnie przesłonić/dziedziczyć ją?
Nie. W Kotlin nie można zadeklarować const val wewnątrz interfejsu lub klasy abstrakcyjnej — jest to dozwolone tylko na poziomie obiektu (object) i top-level. Nie ma odpowiedników static final zmiennych dostępnych do dziedziczenia.
interface Foo { // const val X = "constant" // błąd kompilacji: const 'val' są dozwolone tylko na poziomie top-level, w obiektach lub w obiektach towarzyszących }
Historia
Zespół próbował ponownie wykorzystać stałe tekstowe przez dziedziczenie interfejsu w kilku modułach Android, zadeklarowawszy je jako
const val— otrzymali błąd kompilacji i byli zmuszeni przenieść stałe na top-level, co pogorszyło enkapsulację.
Historia
W projekcie przetransportowano wszystkie pola Java static final do Kotlin
val-właściwości w otwartych klasach, spodziewając się podobnego zachowania (compile-time const), ale stały się zwykłymi właściwościami z getterem. W efekcie czas dostępu się wydłużył, co negatywnie wpłynęło na gorące ścieżki (hot path) aplikacji mikroserwisowej.
Historia
Podczas portowania klas Java zawierających stałe do Kotlin, deweloperzy umieścili stałe wewnątrz companion object, ale napotkali problem z dostępem z kodu Java: stałe były widoczne jako pola samego kompana, a nie klasy, co spowodowało zamieszanie w API i dodatkowe błędy interoperacyjności.