[英]Abstract val with annotation in kotlin android
Can I write:我可以写:
@IdRes
abstract fun getHeaderId(): Int
With a val
instead of a fun
in kotlin?在 kotlin 中使用
val
而不是fun
? It complains I need a backing field or delegate when i write:它抱怨我在写时需要一个支持字段或委托:
@IdRes <-- errors
abstract val headerId: Int
Which is the most idiomatic in this case?在这种情况下,哪个是最惯用的? One-liner with a
fun
or mess around with a backing field (I'm not used to backing fields, maybe it's change-resistance, i have never really used them so i think they are unpleasant)一个
fun
或带有支持字段的混乱(我不习惯支持字段,也许是抗变化性,我从未真正使用过它们,所以我认为它们令人不快)
Since abstract val
or var
is just a function without a backing field it cannot be annotated by IdRes
annotation but there is a workaround.由于抽象
val
或var
只是一个没有支持字段的函数,因此无法通过IdRes
注释进行注释,但有一种解决方法。 You can use it like this:你可以这样使用它:
@get:IdRes
abstract val headerId: Int
EDIT:编辑:
Why does this works?为什么这有效? We need to closer inspect
IdRes
annotation and its source code:我们需要仔细检查
IdRes
注释及其源代码:
@Documented
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface IdRes {
}
As we can see this annotation can be used on methods, parameters, fields and local variables.正如我们所见,此注解可用于方法、参数、字段和局部变量。 When we use
abstract val
it's neither of those since it is abstract and we cannot have abstract fields in Java.当我们使用
abstract val
,它既不是那些,因为它是抽象的,而且在 Java 中我们不能有抽象字段。 Normally equivalent of abstract val something: Int
in Java is:通常相当于
abstract val something: Int
Java 中的abstract val something: Int
是:
private int something
public int getSomething() {
return something;
}
From example, it's easy to see that the private field is what is called backing field of a property and you can't have those as abstract so that was the problem.从示例中,很容易看出私有字段就是所谓的属性的支持字段,您不能将它们抽象为抽象字段,这就是问题所在。
As mentioned in @AtulGupta comment, @theKarlo 's answer does not force the subclass to pass in an IdRes
.正如@AtulGupta 评论中提到的,@theKarlo 的回答不会强制子类传入
IdRes
。
Therefore, an alternative to因此,替代
@IdRes
abstract fun getHeaderId(): Int
and和
@get:IdRes
abstract val headerId: Int
Is to pass the value into the constructor of the class itself, so that the backing field issue can be avoided.是将值传递给类本身的构造函数,这样就可以避免后备字段问题。
For example:例如:
abstract class SomeClass(@IdRes val idRes: Int)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.