Котлин объясняет мне, что касается полей подкачки

Я смотрел официальный учебник Kotlin. Я наткнулся на тему под названием Backing Fields

В нем говорится,

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

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

Я получил вышеуказанное из этой официальной ссылки

Мой вопрос: есть ли поле, указывающее на переменную счетчика?

Может ли кто-нибудь, пожалуйста, предоставить мне пример для поля поддержки или описать меня в понятном слове?

Рассмотрим этот класс

 class SomeClass { var counter: Int = 0 set(value) { if (value >= 0) field = value } } 

В Android Studio перейдите в Main menu -> Tools -> Kotlin -> Show Kotlin Bytecode и нажмите Decompile на панели байт-кода Kotlin.

То, что вы видите, является эквивалентным кодом на Java.

 public final class SomeClass { private int counter; public final int getCounter() { return this.counter; } public final void setCounter(int value) { if(value >= 0) { this.counter = value; } } } 

Ключевое слово field позволяет присвоить значение внутри настраиваемого сеттера. В счетчике kotlin counter = 3 вызывается set(3) . Поэтому, если бы вы определили

 var counter=0 set(value){ counter = value } 

Он будет рекурсивно называть себя до тех пор, пока ваш стек не будет заполнен и ваш процесс не завершится. Ключевое слово field присваивает значение напрямую, не вызывая снова сеттер.

Как это работает, давайте разобраться на примере, рассмотрим это

 class Person { var name: String = "" } 

Если ничего не указано, свойство ( имя ) использует получатель и установщик по умолчанию. Разумеется, он может быть изменен для выполнения любого настраиваемого поведения, без необходимости изменять существующий код:

Поэтому, если вы хотите установить настраиваемое поведение, чтобы назвать свойство, чем мы модифицируем выше класс для этого

 class Person { var name: String = "" get() = field.toUpperCase() set(value) { field = "Name: $value" } } 

Если свойство нуждается в доступе к его собственному значению в пользовательском getter или setter (как в этом случае), для этого требуется создание поля поддержки . Доступ к нему возможен с помощью поля, зарезервированного слова и будет автоматически создан компилятором, когда он обнаружит, что он используется.

A Backing Field – это поле, которое будет генерироваться для свойства в классе, только если оно использует реализацию по умолчанию, по крайней мере, одного из элементов доступа

Исходное поле генерируется только в том случае, если свойство использует стандартную реализацию getter / setter. Если вы видите следующий код с перспективой Java . Это выглядит правильно. Однако в «kotlin» он будет бросать Exception.

  class User{ var firstName : String //backing field generated get() = firstName set(value) { firstName = value } var lastName : String //backing field generated get() = lastName set(value) { lastName = value } val name : String //no backing field generated get() = "{$firstName $lastName}" var address : String = "XYZ" //^because there is no default //^implementation of an accessor } 

В Kotlin приведенный выше фрагмент кода выкинет StackOverflow, потому что когда мы получим доступ или зададим свойство «имя-имя» или «фамилия», будет вызван аксессуар по умолчанию. Итак, в Kotlin «user.firstName =« значение »« такое же, как «user.setFirstName» («значение») Java.

Поэтому, когда вызывается «set (value) {firstName =« value »}, тогда рекурсивный callhappens и компилятор генерируют исключение исключения, потому что мы вызываем setter внутри setter.

Решение этой проблемы связано с полями поддержки пользователей. В Котлине можно использовать обратное поле, используя ключевое слово «field» внутри аксессуаров. Взгляните на исправленный фрагмент кода ниже.

  class User{ var firstName : String get() = field set(value) { field = value } var lastName : String get() = field set(value) { field = value} } } 

Надеюсь, вам это ясно. Если вам нужна дополнительная помощь, спросите меня …

Intereting Posts
Как использовать простое наследование для класса данных? Исключение UninferredParameterTypeConstructor во время сборки, когда общие параметры не указаны явно Динамически загружать пружину xml config В чем разница между обработкой полей через «accessor» и «copy» Аннотации Android с инструментами Kotlin и build 2.3.0 Как запросить тип данных Firebase Firestore Reference? Почему проверка ссылочного равенства возвращает true, когда ссылка различна Класс отсутствует конструктор без аргументов, но я предоставил конструктор без аргументов Как вводить в варт в Котлин? Свойство getter напечатано на Supertype вместо внедрения в Kotlin Ошибка – невозможно изменить заголовок supportActionBar Внедрить только один метод из интерфейса в анонимном классе Как получить переменную окружения из локальной сети с помощью @Value весной? Класс Kotlin NoClassDefFoundError crash Вызов общего метода на нескольких приемниках