programowanieDeweloper Android / Deweloper Backend

Jak działa inicjalizacja stałych wartości (const val) i stałych kompilacji w Kotlinie? Jaka jest różnica w porównaniu do zwykłego val, jakie są ograniczenia, jak to się wykorzystuje w adnotacjach i dlaczego nie zawsze można używać const val tam, gdzie się chce?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Kotlinie słowo kluczowe const val jest używane do deklaracji stałych kompilacji, tj. wartości znanych i obliczanych na etapie kompilacji.

  • const val jest dostępne tylko dla zmiennych na najwyższym poziomie, lub dla właściwości zadeklarowanych w obiektach object lub companion object.
  • Wartość musi być typu: String, prymitywne liczby lub Boolean.
  • Używane jest w adnotacjach i dekoratorach, gdzie wartość musi być wstawiona na etapie kompilacji.

val — to niezmienna zmienna, ale wartość może być przypisana w czasie wykonania, co pozwala na obliczenia lub wywołania funkcji podczas inicjalizacji:

val timestamp = System.currentTimeMillis() // To NIE jest const val const val APP_NAME = "MyApp" // To jest stała kompilacji

W adnotacjach można używać tylko const val, przykład:

const val AUTHOR = "John Doe" @Target(AnnotationTarget.CLASS) adnotacja class Author(val name: String) @Author(AUTHOR) class Example

Jeśli spróbujesz użyć val w takich przypadkach, wystąpi błąd kompilacji.


Pytanie z podstępem

Dlaczego nie można zadeklarować const val wewnątrz zwykłej klasy?

Odpowiedź: Ponieważ const val wymaga, aby zmienna była dostępna na etapie kompilacji, a zmienne instancji klasy są inicjowane dopiero w momencie tworzenia obiektu, więc nie mogą być stałymi kompilacji.

class Example { // Błąd! Nie można tak // const val CLASS_NAME = "MyClass" }

Historia

Złamała się kompilacja, ponieważ programista próbował przekazać wartość obliczoną w czasie wykonania przez adnotację.

Programista zadeklarował:

val version = getVersionFromConfig() @Target(AnnotationTarget.CLASS) adnotacja class Version(val value: String) @Version(version) class App

Projekt nie kompilował się, ponieważ tylko const val można używać w argumentach adnotacji!


Historia

Błąd na Androidzie: próba użycia lokalnych zmiennych jako stałych kluczy w Intent.

class Keys { companion object { val EXTRA_USER_ID = "userId" } } intent.putExtra(Keys.EXTRA_USER_ID, userId)

W niektórych narzędziach lub frameworkach oczekiwany jest const val, a nie zwykły val — w przeciwnym razie IDE lub zasoby Androida nie widzą tych wartości jako stałych kompilacji.


Historia

Użycie niewłaściwego typu dla const val.

const val LIST = listOf(1,2,3) // Błąd! Tylko prymitywy i String.

Nieznajomość ograniczeń typów prowadziła do błędu kompilacji i straty czasu.