¿Para qué sirve el campo de apoyo de Kotlin?

Como desarrollador de Java, el concepto de un campo de respaldo es un poco extraño para mí. Dado:

class Sample { var counter = 0 // the initializer value is written directly to the backing field set(value) { if (value >= 0) field = value } } 

¿Para qué sirve este campo de respaldo? Los documentos de Kotlin decían: Las classs en Kotlin no pueden tener campos. Sin embargo, a veces es necesario tener un campo de respaldo cuando se usan accesadores personalizados . ¿Por qué? ¿Cuál es la diferencia con el uso del nombre de las properties en sí mismo dentro del setter, ej.

  class Sample { var counter = 0 set(value) { if (value >= 0) this.counter = value // or just counter = value? } } 

Porque, por ejemplo, si no tiene la palabra key field , no podrá establecer / get el valor en get() o set(value) . Le permite acceder al campo de respaldo en los descriptores de acceso personalizados.

Este es el código Java equivalente de su muestra:

 class Sample { private int counter = 0; public void setCounter(int value) { if (value >= 0) setCounter(value); } public int getCounter() { return counter; } } 

Aparentemente esto no es bueno, ya que el colocador es solo una recursión infinte en sí mismo, sin cambiar nada. Recuerde en kotlin cada vez que escriba foo.bar = value se traducirá en una llamada setter en lugar de un PUTFIELD .


EDITAR: Kotlin tiene properties mientras que Java tiene campos , que es un concepto de nivel bastante más alto que los campos.

Hay dos types de properties: una con un campo de respaldo y otra sin.

Una propiedad con un campo de respaldo almacenará el valor en forma de un campo. Ese campo hace posible el almacenamiento de valor en la memory. Un ejemplo de dicha propiedad es la first y second properties de Pair . Esa propiedad cambiará la representación en memory de Pair .

Una propiedad sin un campo de respaldo tendrá que almacenar su valor de otras forms que no sea almacenarlo directamente en la memory. Debe ser calculado a partir de otras properties, o, el object mismo. Un ejemplo de dicha propiedad es la propiedad de extensión de indices de List , que no está respaldada por un campo, sino un resultado calculado en function de la propiedad del size . Por lo tanto, no cambiará la representación en memory de List (que no puede hacer en absoluto porque Java está tipada estáticamente).

Los campos de respaldo son buenos para ejecutar la validation o desencadenar events en el cambio de estado. Piense en las veces que ha agregado código a un setter / getter de Java. Los campos de respaldo serían útiles en escenarios similares. Utilizaría campos de respaldo cuando necesitara controlar o tener visibilidad sobre setters / getters.

Al asignar el campo con el nombre del campo en sí, en realidad estás invocando al setter (es decir, set(value) ). En el ejemplo que tiene, this.counter = value se this.counter = value en set (value) hasta que desbordemos nuestra stack. El uso del field evita el código del colocador (o captador).