Есть несколько способов определить константы в Kotlin,
Использование сопутствующего объекта
companion object {
const val ITEM1 = "item1"
const val ITEM2 = "item2"
}
Вы можете использовать вышеуказанный блок сопутствующего объекта внутри любого класса и определить все свои поля внутри самого этого блока. Но есть проблема с этим подходом, документация говорит,
хотя члены сопутствующих объектов выглядят как статические члены в других языках, во время выполнения они все еще являются экземплярами реальных объектов и могут, например, реализовывать интерфейсы.
Когда вы создадите свои константы, используя объект-компаньон, и увидите декомпилированный байт-код , вы увидите что-то похожее ниже:
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;
}
}
Отсюда вы можете легко увидеть то, что сказано в документации, даже если члены сопутствующих объектов выглядят как статические члены в других языках, во время выполнения они все еще являются экземплярами реальных объектов. Он выполняет дополнительную работу, чем требуется.
Теперь приходит другой способ, где нам не нужно использовать объект-компаньон, как показано ниже,
object ApiConstants {
val ITEM1: String = "item1"
}
Опять же, если вы увидите декомпилированную версию байт-кода приведенного выше фрагмента, вы найдете что-то вроде этого,
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";
}
}
Теперь, если вы видите выше декомпилированный код, он создает метод get для каждой переменной. Этот метод get не требуется вообще.
Чтобы избавиться от этих методов get , вы должны использовать const перед val, как показано ниже:
object ApiConstants {
const val ITEM1: String = "item1"
}
Теперь, если вы увидите декомпилированный код приведенного выше фрагмента, вам будет легче его читать, так как он выполняет наименьшее фоновое преобразование для вашего кода.
public final class ApiConstants {
public static final String ITEM1 = "item1";
public static final ApiConstants INSTANCE;
private ApiConstants() {
}
static {
ApiConstants var0 = new ApiConstants();
INSTANCE = var0;
}
}
Так что это лучший способ создания констант.
public static final
полю в Java, используйтеconst val
в своем объекте-компаньоне. Если вы хотитеprivate static final
поле и публичный метод получения, используйтеval
в своем объекте-компаньоне.