所以在内部object
是Kotlin
一个简单的Singleton
. 不同之处在于它是由 Kotlin 语言本身管理的。这样的类仍然需要实例化才能调用它的函数。只是这个实例化是由 Kotlin 进行的,因为对象具有私有构造函数和一个INSTANCE
保存其单个实例的静态字段。让我们看一下这个例子。我是这样object A
定义的:
object A {
fun a() {
}
}
如果我们查看 java 字节码并将其转换为 java,我们将得到:
import kotlin.Metadata;
@Metadata(
mv = {1, 1, 10},
bv = {1, 0, 2},
k = 1,
d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\bÆ\u0002\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\u0003\u001a\u00020\u0004¨\u0006\u0005"},
d2 = {"Lcom/telenor/self_service/app/A;", "", "()V", "a", "", "production sources for module app"}
)
public final class A {
public static final A INSTANCE;
public final void a() {
}
static {
A var0 = new A();
INSTANCE = var0;
}
}
正如您所看到的,只读类主体我们无法理解它是否是一个object
,因为如果我们只使用 Java 创建类似的类,它的行为将是 a class
(not object
)。
public final class B {
public static final B INSTANCE;
public final void b() {
}
static {
B var0 = new B();
INSTANCE = var0;
}
}
但是,当我们尝试像这样从 Java 创建一个新实例时,它会说它A
具有私有构造函数并且无法创建。
new A();
new B();
@Metadata
所以这里的差异是通过定义这种差异的 Kotlin注释产生的。
作为一种解决方案,您可以检查INSTANCE
静态字段,也可以以某种方式读取 Kotlin 元数据 :)