Котлин - как сделать поле только для чтения для внешних классов

у меня есть следующий класс Котлина на Android:

class ThisApplication: Application() {

    lateinit var network: INetwork

    override fun onCreate() {

        super.onCreate()

        network = Network()
    }
}

теперь любой внешний класс может получить ссылку на INetwork, просто выполнив:

application.network

однако это также позволяет внешнему классу перезаписать это значение:

application.network = myNewNetworkReference

Я хочу избежать второго варианта. К сожалению, я не могу сделать поле val потому что его инициализация должна произойти внутри onCreate обратный.

я тоже думал о том, чтобы поле private и выставление его через функцию, например:

private lateinit var network: INetwork
fun getNetwork() = network

однако тот, кто вызывает getNetwork (), все равно может назначить ему новое значение, например:

application.getNetwork() = myNewNetworkReference

как я могу сделать сетевое поле доступным только для чтения внешними классами? Или даже лучше, есть ли способ сделать это val хотя я не могу инициализировать его в конструкторе?

3 ответов


чтобы ограничить доступ из внешних классов,можно изменить видимость аксессоров. Для вашего случая вам нужно private сеттер и public getter с lateinit модификатор:

lateinit var network: INetwork
    private set

или ленивое свойство только для чтения:

val network: INetwork by lazy { Network() }  //you can access private property here, eg. applicationContext

есть некоторые недоразумения от вас об этом коде:

private lateinit var network: INetwork
fun getNetwork() = network

Котлин pass-by-value а то Java браузер. Итак,application.getNetwork() = myNewNetworkReference не является допустимым утверждением. Мы не можем присвоить значение к возвращаемому значению функции.


вы можете изменить видимость геттеров / сеттеров независимо от фактической переменной:

lateinit var network: INetwork
    private set

б val network: INetwork by lazy { ... } работа для вашего сценария?

лямбда-выражение вызывается с первой ссылкой на поле network. Очевидно, что это не то же самое, что отложить инициализацию до OnCreate способ, но это способ сделать это val без необходимости инициализировать его в конструкторе.

есть и другие варианты делегации. документация Котлина стоит проверить.