由于 Kotlin 不允许您在 Java 中的class
likestatic
成员中直接声明常量,因此我们有几个选项来说明如何在 Kotlin 中做到这一点。我的问题是,每个选项的性能成本是多少,哪个更便宜?我不想知道哪个更具可读性或被认为是最佳实践,我只想从性能的角度来看它。
选项 1:使用伴随对象
所以一个看起来像这样的代码:
class Thing {
companion object {
const val TAG = "Thing"
}
...
}
在 Java 中看起来像这样:
public final class Thing {
public static final String TAG = "Thing";
public static final Thing.Companion Companion = new Thing.Companion((DefaultConstructorMarker)null);
public static final class Companion {
private Companion() {
}
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
...
}
它创建这个内部类Companion
并实例化它。这是多么昂贵?
选项 2:将其声明为顶级变量
所以这:
const val TAG = "Thing"
class Thing {
...
}
变成这样:
public final class ThingKt {
public static final String TAG = "Thing";
}
public final class Thing { ... }
它创建一个带有static
成员的新类。这与使用对象存储它有什么不同?
选项 3:使用外部对象
像这样:
object ThingConstants {
const val TAG = "Thing"
}
class Thing { ... }
在 Java 中看起来像这样:
public final class ThingConstants {
public static final String TAG = "Thing";
public static final ThingConstants INSTANCE;
... // Private constructor
}
public final class Thing { ... }
类似于声明为顶级,除了创建的类有一个INSTANCE
在私有构造函数中初始化的字段。与使用顶级变量相比,这有多昂贵?
选项 4:删除 const 修饰符
因此,您只需使用旧的val
:
class Thing {
val TAG = "Thing"
...
}
这对我来说是个谜。它不会创建任何额外的类,但也不会获得const
修饰符的好处。这意味着该类的每个实例都将拥有自己的 实例TAG
,并为其生成 getter 和 setter,对吗?但我也读到JVM 将其优化为常量。所以这个选项比我最初想象的要多。