¿Por qué los inicializadores de propiedad no llaman un setter personalizado?

De la documentation de Kotlin , los progtwigdores personalizados están permitidos:

class Test { var stringRepresentation: String get() = field set(value) { setDataFromString(value) } init { stringRepresentation = "test" } private fun setDataFromString(value: String) { } } 

Pero no puedes tener un setter personalizado sin un getter personalizado (e inicializar desde el bloque init ):

 class Test { // Comstacktion error: "Property must be initialized" var stringRepresentation: String set(value) { setDataFromString(value) } init { stringRepresentation = "test" } private fun setDataFromString(value: String) { } } 

Aunque puede tener un getter personalizado sin un setter personalizado, no hay problema aquí:

 class Test { var stringRepresentation: String get() = field init { stringRepresentation = "test" } private fun setDataFromString(value: String) { } } 

Entonces, ¿por qué no puedes usar un setter personalizado con una propiedad inicializada desde dentro del bloque init , y por qué el bloque init invoca el setter personalizado mientras el inicializador de propiedad lo asigna directamente, sin pasar por el setter personalizado?

 class Test { var stringRepresentation: String = "" // Does not call custom setter set(value) { setDataFromString(value) } init { stringRepresentation = "test" // Calls custom setter } private fun setDataFromString(value: String) { } } 

Los inicializadores de properties no llaman a los configuradores personalizados porque su propósito es proporcionar el valor pnetworkingeterminado.

A diferencia de Java, en Kotlin no solo las variables locales deben inicializarse antes de su primer acceso, sino también las properties de class.

En Java esto es válido.

 public class Test { public String str; public static void main(String[] args) { System.out.println(new Test().str); } } 

En Kotlin esto no es así.

 class Parent { var str: String? } fun main(args: Array<String>) { Parent().str } 

Por esta razón, el progtwigdor personalizado necesita que su propiedad sea inicializada por el inicializador de properties o por el constructor. Eche un vistazo al siguiente ejemplo.

 class Test { var stringRepresentation: String = "a" // Default value. Does not call custom setter get() = field set(value) { println("Setting stringRepresentation property to %s. Current value is %s.".format(value, field)) field = setDataFromString(value) } init { this.stringRepresentation = "b" // Calls custom setter } private fun setDataFromString(value: String): String { println("Setting stringRepresentation property to %s.".format(value)) return value } } fun main(args: Array<String>) { Test().stringRepresentation = "c" // Calls custom setter } 

Propiedad stringRepresentation se inicializa a "a" instanciación de opon de su class sin llamar a setter. Luego se llama al bloque init y establece el valor en "b" usando setter. Luego a "c" usando setter.

  • ¿Cómo implementar un constructor de validation en Kotlin?
  • Kotlin: delegado de propiedad nulable observable
  • Invocar methods en interfaces con generics
  • ¿Dónde deberían savese los files de estado?
  • advertencia: los files JAR en time de ejecución de Kotlin en el classpath deben tener la misma versión
  • Kotlin Closable y SQLiteDatabase en Android
  • FIRESTORE datos persistentes
  • ¿Cómo resolver la ambigüedad de sobrecarga en las references de methods?
  • En Kotlin Lenguaje de progtwigción importancia de varargs en términos de usos
  • Kotlin: ¿Podemos usar @Subscribe de EventBus (GreenRobot) en Kotlin?
  • Errores de compilation de Codename One relacionados con Kotlin