Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 598
Bitcoin Cash - ADA enthusiast Avatar asked Aug 20 '17 00:08

Bitcoin Cash - ADA enthusiast


People also ask

Does Kotlin have public fields?

Classes, objects, interfaces, constructors, and functions, as well as properties and their setters, can have visibility modifiers. Getters always have the same visibility as their properties. There are four visibility modifiers in Kotlin: private , protected , internal , and public .

What is the difference between field and property in Kotlin?

Properties vs fieldsField is just a class member variable that hold a value. It can be read-only or mutable and marked with any access modifier such as public or private . Property is more complex element that contain a private field and accessors.

What is get () in Kotlin?

In Kotlin, setter is used to set the value of any variable and getter is used to get the value. Getters and Setters are auto-generated in the code. Let's define a property 'name', in a class, 'Company'. The data type of 'name' is String and we shall initialize it with some default value.

What is a sealed class Kotlin?

A sealed class defines a set of subclasses within it. It is used when it is known in advance that a type will conform to one of the subclass types. Sealed classes ensure type safety by restricting the types to be matched at compile-time rather than at runtime.


1 Answers

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.

like image 102
BakaWaii Avatar answered Oct 20 '22 22:10

BakaWaii