Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract val with annotation in kotlin android

Tags:

android

kotlin

Can I write:

@IdRes
abstract fun getHeaderId(): Int

With a val instead of a fun in kotlin? 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)

like image 974
Adam Avatar asked Dec 19 '18 10:12

Adam


Video Answer


2 Answers

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. 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:

@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. Normally equivalent of abstract val something: Int in Java is:

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.

like image 136
TheKarlo95 Avatar answered Nov 17 '22 01:11

TheKarlo95


As mentioned in @AtulGupta comment, @theKarlo 's answer does not force the subclass to pass in an 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 and the subclass is forced to pass in an IdRes.

For example:

abstract class SomeClass(@IdRes val idRes: Int)
like image 34
Jeff Padgett Avatar answered Nov 17 '22 00:11

Jeff Padgett