Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: const val vs val

Tags:

android

kotlin

I understand in Kotlin const val is used to declare constants and val is for readonly properties. However, I'm wondering in the following case, which one is more suitable to use.

Assume I have a fragment which needs a key to use for saveInstanceState and restoreInstanceState. I'm wondering which one of the following 2 options is better:

Option 1:

class MyFragment {
    private val MY_KEY = "my_key"
    ...
}

Option 2:

private const val MY_KEY = "my_key" // declared in the same file.

class MyFragment {
    ...
}

I'd prefer the #option 2 since it makes it clear that MY_KEY is a constant and the value is determined in compile time. However since it's declared on the top level, it costs a class i.e. MyFragmentKt (assume the file name is MyFragment.kt) to be created in the compiled java code. In #option 1, no extra class is generated and although MY_KEY's value is going to be assigned at runtime and not constant, that makes no difference in how it's used in this specific case.

So although I personally prefer #option 2, my analysis makes me think #option 1 is not worse, if not better. I'm just wondering how other developers think about this and if there are any other benefits of #option 2 that I haven't thought of. Thanks.

like image 586
H.Nguyen Avatar asked Feb 07 '18 10:02

H.Nguyen


People also ask

What is difference between Val and const Val in Kotlin?

In Kotlin, val is also used for declaring a variable. Both "val" and "const val" are used for declaring read-only properties of a class. The variables declared as const are initialized at the runtime. val deals with the immutable property of a class, that is, only read-only variables can be declared using val.

Is Val immutable in Kotlin?

Kotlin: val is read-only not immutable.


2 Answers

Every time you write a (non-inline) lambda expression, you have created another class. Compared to that, creating a single class to hold top-level declarations seems minor.

Furthermore, if all you have at the top level is a constant declaration, it will be inlined into each use site (by specification) so the owning class itself will become unreferenced and therefore targetable by ProGuard's minimization. It will most likely not appear in your production APK.

like image 99
Marko Topolnik Avatar answered Sep 27 '22 18:09

Marko Topolnik


There is not only a semantic difference between the two options.

Option 1 (val inside the class) is an instance field.

Option 2 (top-level const val) is a top-level "static" member (roughly, since static doesn't exist in Kotlin.)

This is why you have a MyFragmentKt class generated: top-level members are compiled into a class of the name [Filename]Kt.

I would consider a third option:

class MyFragment {
    companion object {
        private const val MY_KEY = "my_key"
    }
}

This way, MY_KEY is (from Java) a static member of the MyFragment class, since JvmStatic is inferred for const variables. There will be a Companion class generated (but it will be empty).

Since your original approach was a field inside the class I feel like the companion object/static constant might be preferable.

More about companion objects vs Java's static

like image 32
Salem Avatar answered Sep 27 '22 19:09

Salem