115 votes

Qu'est-ce que Kotlin Backing Field?

En tant que développeur Java, le concept d'un champ de stockage est un peu étranger à moi. Donnée:

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

Qu'est-ce champ de stockage? Kotlin docs dit: Classes de Kotlin ne peut pas avoir de champs. Toutefois, il est parfois nécessaire d'avoir un champ de stockage lors de l'utilisation de la coutume des accesseurs. Pourquoi? Quel est la différence avec l'aide des propriétés nom lui-même à l'intérieur de l'incubateur, par exemple.

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

102voto

glee8e Points 3769

Parce que, disons que si vous n'avez pas d' field mot-clé, vous ne serez pas en mesure de créer/récupérer la valeur dans l' get() ou set(value). Il vous permet d'accéder à la sauvegarde de champ dans la coutume des accesseurs.

C'est l'équivalent du code Java de votre échantillon:

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

Apparemment ce n'est pas bon, comme le setter est juste une récursivité infinie en lui-même, de ne jamais rien changer. Rappelez-vous dans kotlin chaque fois que vous écrivez foo.bar = value il sera traduit dans un setter appel, au lieu d'un PUTFIELD.


EDIT: Java a des champs , tandis que Kotlin a des propriétés, ce qui est un niveau plus élevé concept de champs.

Il existe deux types de propriétés: l'une avec un champ de stockage, l'autre sans.

Une propriété avec un champ de stockage permettra de stocker la valeur dans la forme d'un champ. Ce champ permet de stocker la valeur dans la mémoire possible. Un exemple de cette propriété est l' first et second propriétés de l' Pair. Cette propriété va changer la représentation en mémoire d' Pair.

Une propriété sans la sauvegarde de champ pour stocker leur valeur dans d'autres moyens que de les stocker dans la mémoire. Il doit être calculé à partir d'autres propriétés, ou, l'objet lui-même. Un exemple de cette propriété est l' indices extension de la propriété de l' List, ce qui n'est pas soutenu par un champ, mais un calculées selon size de la propriété. Afin de ne pas modifier la représentation en mémoire d' List (qui elle ne peut pas le faire parce que Java est statiquement typé).

48voto

thedarkpassenger Points 1655

D'abord, j'ai moi aussi eu un moment difficile la compréhension de ce concept. Alors laissez-moi vous expliquer cela avec l'aide d'un exemple.

Considérer cette classe Kotlin

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

Maintenant, quand on regarde le code, nous pouvons voir qu'il a 2 propriétés.e - size (par défaut accesseurs) et isEmpty(avec les accesseurs personnalisés). Mais il a seulement 1 champ soit size. De comprendre qu'il a seulement 1 domaine, nous permettent de voir la Java équivalent de cette classe.

Allez dans Outils -> Kotlin -> Afficher Kotlin ByteCode dans Android Studio. Cliquez sur le Décompiler.

   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;
   }
}

Clairement, nous pouvons voir que la classe java a seulement getter et setter fonctions pour isEmpty, et il n'y a pas de champ déclaré. De même, dans Kotlin, il n'y a pas de champ de stockage pour les biens isEmpty, étant donné que la propriété ne dépend pas de ce domaine. Donc pas de champ de stockage.


Maintenant, nous allons nous retirer la coutume de lecture et de définition de l' isEmpty de la propriété.

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

Et Java équivalent de la classe ci-dessus est

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;
   }
}

Ici, nous voyons à la fois les champs size et isEmpty. isEmpty est un champ de stockage, car les getter et setter pour isEmpty de la propriété en dépendent.

11voto

Mark Mucha Points 1248

Champs de sauvegarde sont bonnes pour l'exécution de la validation ou le déclenchement des événements de changement d'état. Pensez à la fois que vous avez ajouté le code pour Java setter/getter. Champs de sauvegarde serait utile dans des scénarios similaires. Vous utilisez des champs de sauvegarde lorsque vous avez besoin de contrôler ou d'avoir de la visibilité sur les setters/getters.

Lors de l'attribution du champ avec le nom du champ lui-même, vous êtes en fait en invoquant le setter (c - set(value)). Dans l'exemple que vous avez, this.counter = value serait recurse en jeu(valeur) jusqu'à ce que nous débordement de notre stack. À l'aide de field contourne l'ouvreur (ou de lecture) du code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X