Search code examples
fieldkotlinreadonlykotlin-lateinit

Kotlin - How to make field read-only for external classes


I have the following Kotlin class on Android:

class ThisApplication: Application() {

    lateinit var network: INetwork

    override fun onCreate() {

        super.onCreate()

        network = Network()
    }
}

Now, any external class can get the INetwork reference by simply doing:

application.network

However, that also makes it possible for an external class to overwrite that value:

application.network = myNewNetworkReference

I want to avoid the second option. Unfortunately, I can't make the field val because its initialization needs to happen inside the onCreate callback.

I also thought about making the field private and exposing it through a function, like this:

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

However, whoever calls getNetwork() can still assign a new value to it, like so:

application.getNetwork() = myNewNetworkReference

How can I make the network field to be read-only by external classes? Or even better, is there a way to make it val even though I can't initialize it inside a constructor?


Solution

  • To restrict the access from the external classes, you can change the visibility of accessors. For your case, you need private setter and public getter with lateinit modifier:

    lateinit var network: INetwork
        private set
    

    Or a read-only lazy property:

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

    There are some misunderstanding from you about this code:

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

    Kotlin is pass-by-value as what Java does. So, application.getNetwork() = myNewNetworkReference is not a valid statement. We cannot assign value to the return value of a function.