Можно ли записать в const val объект кроме строки в Kotlin
Что проверяют
Понимаете ли вы разницу между константой времени компиляции и просто неизменяемой ссылкой. Следом обычно спрашивают, чем const val отличается от val в companion object и что увидит Java-код, который обращается к такой константе.
Как отвечать
Короткий ответ: нельзя. const val принимает только значение, которое компилятор знает заранее, и набор типов у него ограничен:
- допустимые типы:
Stringи примитивыInt,Long,Short,Byte,Double,Float,Char,Boolean. Экземпляр data class, список, массив илиenumвconstне положить; - инициализатор: литерал или выражение из других констант.
60 * 1000и строковый шаблон"$BASE/users"изconst-строки подходят, вызов функции вродеlistOf()уже нет; - место объявления: верхний уровень файла,
objectилиcompanion object. Внутри обычного класса или функцииconstне пишется; - без кастомного геттера.
Почему так: компилятор подставляет значение прямо в место использования, как Java делает со static final примитивами. Поэтому const годится для аргументов аннотаций, например строки запроса в @Query у Room или ключа в @SerializedName, а обычный val там не скомпилируется. В байткоде такая константа становится полем public static final без геттера.
Если нужен один неизменяемый объект на весь класс, пишут обычный val в object или companion object. Он создаётся один раз при инициализации класса, но это уже вычисление во время выполнения. Чтобы Java видела такое свойство полем, а не геттером, добавляют @JvmField.
Где спотыкаются
Говорят, что const val можно сделать из data class, если все его поля константы. Нельзя: объект создаёт конструктор во время выполнения, компилятор его не вычисляет.
Путают val и const val, считая val «почти константой». val запрещает только переприсваивание ссылки, а объект за ней может быть изменяемым, например val list = mutableListOf<Int>().
Забывают про подстановку значения. Если константа объявлена в библиотеке и её значение поменялось, модули, собранные со старой версией, продолжат видеть старое значение до пересборки.