Kotlin: cómo hacer que el campo sea de solo lectura para las classs externas

Tengo la siguiente class de Kotlin en Android:

class ThisApplication: Application() { lateinit var network: INetwork override fun onCreate() { super.onCreate() network = Network() } } 

Ahora, cualquier class externa puede get la reference de INetwork simplemente haciendo:

 application.network 

Sin embargo, eso también hace posible que una class externa sobrescriba ese valor:

 application.network = myNewNetworkReference 

Quiero evitar la segunda opción. Desafortunadamente, no puedo hacer el campo val porque su initialization debe ocurrir dentro de la onCreate llamada onCreate .

También pensé en hacer el campo privado y exponerlo a través de una function, como esta:

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

Sin embargo, quien llama a getNetwork () aún puede asignarle un nuevo valor, como se muestra a continuación:

 application.getNetwork() = myNewNetworkReference 

¿Cómo puedo hacer que el campo de networking sea de solo lectura por classs externas? O mejor aún, ¿hay alguna manera de hacerlo val aunque no pueda inicializarlo dentro de un constructor?

Para restringir el acceso de las classs externas, puede cambiar la visibilidad de los usuarios. Para su caso, necesita getter private y public getter con modificador lateinit :

 lateinit var network: INetwork private set 

O una propiedad floja de solo lectura:

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

Hay algunos malentendidos acerca de este código:

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

Kotlin pasa por valor como lo hace Java . Por lo tanto, application.getNetwork() = myNewNetworkReference no es una statement válida. No podemos asignar valor al valor de retorno de una function.

Puede modificar la visibilidad de los getters / setters independientemente de la variable real:

 lateinit var network: INetwork private set 

¿ val network: INetwork by lazy { ... } para su escenario?

La expresión lambda se llama con la primera reference a la network campo. Obviamente, esto no es lo mismo que diferir la initialization al método OnCreate , pero es una forma de hacerlo val sin tener que inicializarlo en el constructor.

También hay otras opciones de delegación. La documentation de Kotlin vale la pena echarle un vistazo.