¿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 comstackr el código de testing de unidad de Kotlin que usa hamcrest 'is'
  • Kotlin start Application crash
  • Setter no pidió Kotlin POJO
  • Cómo modificar la fuente de class para anotar la class Kotlin mediante el plugin Intellij Idea personalizado
  • (Desconocido Fuente: 7) error in kotlin android
  • El constructor de SAM networkingundante no se puede eliminar para la function declarada de Kotlin, pero funciona en la function declarada de Java
  • ¿Por qué una propiedad tipada genérica se puede anular?
  • Un equivalente de text para la imageView
  • No se puede build un proyecto con Android Studio 3.0 + DataBinding + Kotlin
  • El filtrado de la entidad Hibernate con @Filter no filtra
  • ¿Qué tipo de time de compilation debo asignar para recibir un valor de retorno de java.util.Map <TextAttribute,?>