Что такое поле для подбора Котлина?

Как разработчик Java, концепция поля поддержки немного чуждо мне. Данный:

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

Для чего это полезно? Kotlin docs сказал: Классы в Котлине не могут иметь поля. Однако иногда при использовании пользовательских аксессуаров необходимо иметь резервное поле . Зачем? В чем разница с использованием самого имени свойства внутри установщика, например.

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

Потому что, скажем, если у вас нет ключевого слова field , вы не сможете фактически установить / получить значение в get() или set(value) . Он позволяет вам получить доступ к полю резервного копирования в пользовательских аксессуарах.

Это эквивалентный код Java вашего образца:

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

По-видимому, это нехорошо, так как сеттер – это просто инфинитная рекурсия в себя, никогда ничего не меняя. Помните в kotlin всякий раз, когда вы пишете foo.bar = value он будет переведен в вызов setter вместо PUTFIELD .


EDIT: у Kotlin есть свойства, в то время как у java есть поля , что представляет собой концепцию более высокого уровня, чем поля.

Существует два типа свойств: один с опорным полем, один без него.

Свойство с опорным полем сохранит значение в форме поля. Это поле позволяет сохранить ценность в памяти. Примером такого свойства является first и second свойства Pair . Это свойство изменит представление Pair в памяти.

Свойству без поля поддержки придется хранить свое значение другими способами, чем непосредственно хранить его в памяти. Он должен быть вычислен из других свойств или самого объекта. Примером такого свойства является свойство расширения indices List , которое не поддерживается полем, а вычисленным результатом, основанным на свойстве size . Таким образом, это не изменит представление в List в памяти (которое он не может сделать вообще, потому что Java статически типизирован).

Поддерживающие поля хороши для запуска проверки или запуска событий при изменении состояния. Подумайте о том, как вы добавили код в Java setter / getter. В подобных сценариях поле будет полезным. Вы должны использовать резервные поля, когда вам нужно контролировать или иметь видимость по сеттерам / геттерам.

При назначении поля самому имени поля вы фактически вызываете установщик (т. Е. set(value) ). В приведенном примере this.counter = value будет возвращаться в set (value), пока мы не переполним наш стек. Использование field обходит код сеттера (или геттера).