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



как разработчик 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?
}
}
850   3  

3 ответов:

, потому что, скажем, если у вас нет 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;
    }
}

по-видимому, это не хорошо, так как сеттер-Это просто бесконечная рекурсия в себя, никогда ничего не меняющая. Помните в Котлине, когда вы пишете foo.bar = value он будет переведен в сеттер звоните вместо PUTFIELD.


EDIT: Java имеет поля в то время как Котлин имеет свойства, что является довольно высоким уровнем концепции, чем поля.

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

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

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

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

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

первоначально мне тоже было трудно понять эту концепцию. Поэтому позвольте мне объяснить вам это на примере.

рассмотрим этот класс Котлина

class DummyClass {
    var size = 0;
    var isEmpty
        get() = size == 0
        set(value) {
            size = size * 2
        }
}

теперь, когда мы смотрим на код, мы можем видеть, что он имеет 2 свойства т. е. - size (С аксессорами по умолчанию) и isEmpty(с пользовательскими методами доступа). Но он имеет только 1 поле, т. е. size. Чтобы понять, что он имеет только 1 поле, давайте посмотрим Java-эквивалент этого класса.

перейти к Инструменты - > Kotlin - > показать байт-код Kotlin в Android Studio. Нажмите на кнопку декомпилировать.

   public final class DummyClass {
   private int size;

   public final int getSize() {
      return this.size;
   }

   public final void setSize(int var1) {
      this.size = var1;
   }

   public final boolean isEmpty() {
      return this.size == 0;
   }

   public final void setEmpty(boolean value) {
      this.size *= 2;
   }
}

ясно, что класс java имеет только функции getter и setter для isEmpty, и для него нет объявленного поля. Точно так же в Котлине нет резервного поля для свойства isEmpty, так как свойство не зависит от этого поля вообще. Таким образом, нет резервного поля.


теперь давайте удалим пользовательский геттер и сеттер isEmpty свойство.

class DummyClass {
    var size = 0;
    var isEmpty = false
}

и эквивалент Java вышеуказанного класса

public final class DummyClass {
   private int size;
   private boolean isEmpty;

   public final int getSize() {
      return this.size;
   }

   public final void setSize(int var1) {
      this.size = var1;
   }

   public final boolean isEmpty() {
      return this.isEmpty;
   }

   public final void setEmpty(boolean var1) {
      this.isEmpty = var1;
   }
}

здесь мы видим, как поля size и isEmpty. isEmpty - это резервное поле, потому что геттер и сеттер для isEmpty свойство зависит от него.

Comments

    Ничего не найдено.