Kotlin: Inicializa el atributo de class en el constructor

Creo una class Kotlin con un atributo de class, que quiero inicializar en el constructor:

public class TestClass { private var context : Context? = null // Nullable attribute public constructor(context : Context) { this.context = context } public fun doSomeVoodoo() { val text : String = context!!.getString(R.string.abc_action_bar_home_description) } } 

Desafortunadamente tengo que declarar el atributo como Nullable con el "?" signo, aunque el atributo se inicializará en el constructor. Declarar este atributo como atributo Nullable hace que siempre sea necesario forzar un valor no nulo con "!! o para proporcionar un cheque nulo con "?".

¿Hay alguna forma de evitar esto, si el atributo de class se inicializará en el constructor? Me gustaría apreciar una solución como esta:

 public class TestClass { private var context : Context // Non-Nullable attribute public constructor(context : Context) { this.context = context } public fun doSomeVoodoo() { val text : String = context.getString(R.string.abc_action_bar_home_description) } } 

Si lo único que estás haciendo en el constructor es una asignación, entonces podrías usar el Constructor Primario con una Propiedad privada.

p.ej:

 public class TestClass(private var context: Context) { public fun doSomeVoodoo() { val text = context.getString(R.string.abc_...) } } 

Como muestra D3xter, tiene la opción de configurarlo en el constructor. También tienes otras opciones. Aquí todos ellos son …

Cree la propiedad dentro del constructor (según @D3xter), este es el caso más común para las properties simples inicializadas directamente por el constructor primario :

 class TestClass(private val context: Context) { fun doSomeVoodoo() { val text : String = context.getString() } } 

Puede declarar la propiedad val y no inicializarla, suponiendo que todos los constructores posibles la inicialicen (según su segundo ejemplo en la pregunta). Esto es normal cuando tienes más de un constructor que podría inicializar un valor de manera diferente :

 public class TestClass { private val context: Context public constructor(context : Context) { this.context = context } // alternative constructor public constructor(pre: PreContext) { this.context = pre.readContext() } public fun doSomeVoodoo() { val text : String = context.getString() } } 

Puede pasar parameters de constructor que no son declaraciones de propiedad y luego usarlos dentro de las inicializaciones de properties. Esto es común cuando tiene inicializaciones más complejas o necesita usar properties delegadas :

 class TestClass(context: PreContext) { private val context : Context by lazy { context.readContext() } private val other: List<Items> = run { context.items.map { it.tag }.filterNotNull() } private val simpleThing = context.getSimple() fun doSomeVoodoo() { val text : String = context.getString() } } 

Usar el modificador de lateinit hora cuando no puede inicializar el valor durante la construcción, pero está seguro de que se realizará antes de su primer acceso de lectura. Esto es común cuando una dependency injection, un contenedor IoC o algo crea una versión vacía de su class y luego la inicializa de inmediato :

 class TestClass() { private lateinit var context : Context // set by something else after construction fun doSomeVoodoo() { val text : String = context.getString() } } 

Para lateinit la propiedad debe ser actualmente una var y no funciona con types primitivos.

También puede declarar una propiedad var y no inicializarla si usa un delegado diseñado para tal fin, como Delegates.notNull() . Esto es similar a lateinit y común cuando quiere una var que no tiene un estado inicial, pero se establece más tarde después de la construcción en un punto desconocido en el time :

 public class TestClass() { private var context: Context by Delegates.notNull() public fun doSomeVoodoo() { // if context is not set before this is called, an exception is thrown val text : String = context.getString() } } 
  • Kotlin: diferencia entre el object y el object acompañante en una class
  • Cadena para duplicar en Android / Kotlin
  • Kotlin reflect proguard SmallSortedMapa
  • Parámetro constructor de Kotlin sin getter
  • Extensiones de Kotlin para Android y menu
  • Reino que devuelve datos obsoletos
  • ¿Qué es el doble explosión de Kotlin?
  • ¿Cómo crear una class estática en Kotlin?
  • Google Assistant SDK rechaza el canal autenticado como "UNAUTHENTICATED"
  • Modo correcto de consulta de Android Kotlin Realm + devolución de elementos no administrados en Bg Thread
  • Elegir una estrategia a través de la configuration JSON