如何使用Kotlin精简构造函数语法来使用Room库的@Ignore注解?

我试图使用android室库和Kotlin的紧凑语法指定一个构造函数与默认参数值。 像这样的东西:

@Entity class MyEntity(var myString:String = "non-trivial string") { @PrimaryKey(autoGenerate = true) var myIndex:Int = 0 } 

但是我得到这个警告信息:

有多个好的构造函数,Room会选择无参数的构造函数。 您可以使用@Ignore注释来消除不需要的构造函数。

语法允许在这个紧凑的Kotlin风格的构造函数中写入Room的@Ignore注释吗?

我知道我可以做这样的事情来消除这个警告信息,但是它更冗长。 这也使得构造函数arg的默认值显得冗余/无益:

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

我怎样才能宣布一个房间的实体,但仍利用Kotlin的简洁性?

非常感谢你。

如果要将注释添加到主构造函数,则必须添加constructor关键字:

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

该文件指出:

如果主构造函数没有任何注释或可见性修饰符,则可以省略constructor关键字。

这个怎么样:

 @Entity class MyEntity( var myString: String = "non-trivial string", @PrimaryKey(autoGenerate = true) var myIndex: Int = 0 ) 

我们来看这个代码:

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

如果你反编译它,你得到的是相当于下面的一段Java代码(省略了getter / setter):

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

因此,你得到2个构造函数+ 1个合成构造函数。 这不是疯狂的,因为它必须支持带有字符串参数的构造函数和没有任何参数的构造函数(并且记住MyEntity可以从Java代码实例化,所以Kotlin编译器必须创建两个构造函数)。

如果你写这个代码:

 class MyEntity(myString: String?) { val myString: String init { if (myString == null) { this.myString = "" } else { this.myString = myString } } } 

你得到的字节码相当于下面的Java代码(省略了getter / setter):

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

使用Kotlin代码的第二部分,即使它不完全等同于Kotlin代码的第一个片段,也应该能够删除警告并保持myString属性不可为空,因为您始终需要在构造函数中提供参数。