Kotlin - How to make a read-only field 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 link by simply doing:

 application.network 

However, it also allows the outer class to overwrite this value:

 application.network = myNewNetworkReference 

I want to avoid the second option. Unfortunately, I cannot create a val field because it must be initialized inside the onCreate .

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

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

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

 application.getNetwork() = myNewNetworkReference 

How can I make a network field read-only by external classes? Or even better, is there a way to do this val , although I cannot initialize it inside the constructor?

+5
source share
3 answers

To restrict access to external classes, you can change the visibility of accessories. For your case, you will need a private setter and public getter with the lateinit modifier:

 lateinit var network: INetwork private set 

Or a lazy read-only property:

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

Some misunderstanding arises from this code:

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

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

+3
source

You can change the visibility of getters / setters regardless of the actual variable:

 lateinit var network: INetwork private set 
+3
source

Will val network: INetwork by lazy { ... } work for your scenario?

The lambda expression is invoked with the first reference to the network field. Obviously, this is not the same as deferring initialization to the OnCreate method, but it is a way to make it val without having to initialize it in the constructor.

There are other delegation options. The Kotlin documentation is worth checking out.

+2
source

Source: https://habr.com/ru/post/1271020/


All Articles