2 votes

Comment utiliser l'annotation @Ignore de la bibliothèque Room avec la syntaxe des constructeurs compacts de Kotlin ?

J'essaie d'utiliser à la fois la bibliothèque Android Room et la syntaxe compacte de Kotlin pour spécifier un constructeur avec des valeurs d'argument par défaut. Quelque chose comme ceci :

@Entity
class MyEntity(var myString:String = "non-trivial string") {

    @PrimaryKey(autoGenerate = true)
    var myIndex:Int = 0
}

Mais je reçois ce message d'avertissement :

Il existe plusieurs bons constructeurs et Room choisira le constructeur sans argument. Vous pouvez utiliser l'annotation @Ignore pour éliminer les constructeurs indésirables.

Où la syntaxe permet-elle d'écrire l'annotation @Ignore de Room avec ce style compact de constructeur Kotlin ?

Je sais que je peux faire quelque chose comme ceci pour éliminer ce message d'avertissement, mais c'est plus verbeux. De plus, la valeur par défaut de l'arg du constructeur semble redondante et inutile :

@Entity
class MyEntity() {

    @Ignore
    constructor(myString:String = "non-trivial string") : this() {
        this.myString = myString
    }

    @PrimaryKey(autoGenerate = true)
    var myIndex:Int = 0

    var myString:String? = null
}

Comment déclarer une entité Room tout en profitant de la brièveté de Kotlin ?

Je vous remercie de votre attention.

3voto

s1m0nw1 Points 21698

Si vous souhaitez ajouter des annotations au constructeur primaire, la fonction constructor doit être ajouté :

class MyEntity @Ignore constructor(var myString:String = "non-trivial string")

Les la documentation États :

Si le constructeur primaire n'a pas d'annotations ou de modificateurs de visibilité, la fonction constructor peut être omis.

1voto

LordRaydenMK Points 7908

Que pensez-vous de ceci ?

@Entity
class MyEntity(
    var myString: String = "non-trivial string",

    @PrimaryKey(autoGenerate = true)
    var myIndex: Int = 0
)

1voto

user2340612 Points 1339

Prenons ce code :

class MyEntity(var myString: String = "default value")

Si vous le décompilez, vous obtenez l'équivalent du morceau de code Java suivant (getter/setter omis) :

public final class MyEntity {
  @NotNull
  private String myString;

  // getters and setters omitted

  public MyEntity(@NotNull String myString) {
     Intrinsics.checkParameterIsNotNull(myString, "myString");
     super();
     this.myString = myString;
  }

  // $FF: synthetic method
  public MyEntity(String var1, int var2, DefaultConstructorMarker var3) {
     if ((var2 & 1) != 0) {
        var1 = "default value";
     }

     this(var1);
  }

  public MyEntity() {
     this((String)null, 1, (DefaultConstructorMarker)null);
  }
}

On obtient donc 2 constructeurs + 1 constructeur synthétique. Ce n'est pas fou, puisqu'il faut supporter à la fois un constructeur avec un argument de type chaîne et un constructeur sans aucun argument (et rappelez-vous que MyEntity peut être instancié à partir du code Java, de sorte que le compilateur Kotlin doit créer les deux constructeurs).

Si, au lieu de cela, vous écrivez ce code :

class MyEntity(myString: String?) {

    val myString: String

    init {
        if (myString == null) {
            this.myString = ""
        } else {
            this.myString = myString
        }
    }

}

Le bytecode que vous obtenez est équivalent au code Java suivant (getter/setter omis) :

public final class MyEntity {
  @NotNull
  private String myString;

  // getter and setter omitted

  public MyEntity(@Nullable String myString) {
     if (myString == null) {
        this.myString = "default value";
     } else {
        this.myString = myString;
     }

  }
}

Avec le deuxième extrait de code Kotlin, vous devriez être en mesure de supprimer l'avertissement et de conserver l'élément myString non nullable, même si ce n'est pas exactement équivalent au premier extrait de code Kotlin puisque vous devez toujours fournir un argument dans le constructeur.

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