There are a few ways you can define constants in Kotlin,
Using companion object
companion object {
const val ITEM1 = "item1"
const val ITEM2 = "item2"
}
you can use above companion object block inside any class and define all your fields inside this block itself. But there is a problem with this approach, the documentation says,
even though the members of companion objects look like static members in other languages, at runtime those are still instance members of real objects, and can, for example, implement interfaces.
When you create your constants using companion object, and see the decompiled bytecode, you'll something like below,
ClassName.Companion Companion = ClassName.Companion.$$INSTANCE;
@NotNull
String ITEM1 = "item1";
@NotNull
String ITEM2 = "item2";
public static final class Companion {
@NotNull
private static final String ITEM1 = "item1";
@NotNull
public static final String ITEM2 = "item2";
// $FF: synthetic field
static final ClassName.Companion $$INSTANCE;
private Companion() {
}
static {
ClassName.Companion var0 = new ClassName.Companion();
$$INSTANCE = var0;
}
}
From here you can easily see what the documentation said, even though the members of companion objects look like static members in other languages, at runtime those are still instance members of real objects It's doing extra work than required.
Now comes another way, where we don't need to use companion object like below,
object ApiConstants {
val ITEM1: String = "item1"
}
Again if you see the decompiled version of the byte code of above snippet, you'll find something like this,
public final class ApiConstants {
private static final String ITEM1 = "item1";
public static final ApiConstants INSTANCE;
public final String getITEM1() {
return ITEM1;
}
private ApiConstants() {
}
static {
ApiConstants var0 = new ApiConstants();
INSTANCE = var0;
CONNECT_TIMEOUT = "item1";
}
}
Now if you see the above decompiled code, it's creating get method for each variable. This get method is not required at all.
To get rid of these get methods, you should use const before val like below,
object ApiConstants {
const val ITEM1: String = "item1"
}
Now if you see the decompiled code of above snippet, you'll find it easier to read as it does the least background conversion for your code.
public final class ApiConstants {
public static final String ITEM1 = "item1";
public static final ApiConstants INSTANCE;
private ApiConstants() {
}
static {
ApiConstants var0 = new ApiConstants();
INSTANCE = var0;
}
}
So this is the best way to create constants.