简体   繁体   English

kotlin android 中带注释的抽象 val

[英]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.由于抽象valvar只是一个没有支持字段的函数,因此无法通过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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM