盒子
盒子
文章目录
  1. 对象声明
  2. 伴生对象
  3. 对象表达式

Kotlin原理-object关键字

object关键字有下面的三种用法:

  1. 对象声明
  2. 伴生对象
  3. 对象表达式

我们逐一来看看它们的实现原理

对象声明

object类可以看成是java里面的单例模式在kotlin的便捷实现:

1
2
3
4
5
6
7
8
9
10
11
12
object TestObject {
const val TAG = "TestObject"

fun foo() {
}
}

// kotlin 中调用
TestObject.foo()

// java 中调用
TestObject.INSTANCE.foo();

从java的用法里面能看出来,对象声明的原理实际上是将其转换成了java的单例模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public final class TestObject {
@NotNull
public static final String TAG = "TestObject";
@NotNull
public static final TestObject INSTANCE;

public final void foo() {
}

private TestObject() {
}

static {
TestObject var0 = new TestObject();
INSTANCE = var0;
}
}

如果与java混用的时候,需要使用INSTANCE获取单例比较麻烦,可以使用@JvmStatic注解将方法修饰成静态方法:

1
2
3
4
5
object TestObject {
@JvmStatic
fun foo() {
}
}

转换出来的java类就会把foo()定义为静态方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public final class TestObject {
@NotNull
public static final TestObject INSTANCE;

// 这里是静态方法
@JvmStatic
public static final void foo() {
}

private TestObject() {
}

static {
TestObject var0 = new TestObject();
INSTANCE = var0;
}
}

伴生对象

Kotlin中并没有静态成员的概念,但是我们可以使用伴生对象达到类似的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
class TestClass {
companion object {
var data = 123
fun foo() {}
}
}


// kotlin 中调用
TestClass.foo()

// java 中调用
TestClass.Companion.foo();

同样可以在java调用中看出来它实际是生成了TestClass的Companion静态内部类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public final class TestClass {
private static int data = 123;

@NotNull
public static final TestClass.Companion Companion = new TestClass.Companion((DefaultConstructorMarker)null);

...

public static final class Companion {
public final void foo() {
}

private Companion() {
}

public final int getData() {
return TestClass.data;
}

public final void setData(int var1) {
TestClass.data = var1;
}
...
}
}

同样在java调用的时候需要引用Companion静态成员变量,我们可以用@JvmField和@JvmStatic去简化:

1
2
3
4
5
6
7
8
9
class TestClass {
companion object {
@JvmField
var data = 123

@JvmStatic
fun foo() {}
}
}

上面kotlin代码转换的java代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class TestClass {
public static int data = 123;

public static final TestClass.Companion Companion = new TestClass.Companion((DefaultConstructorMarker)null);

public static final void foo() {
Companion.foo();
}

public static final class Companion {
@JvmStatic
public final void foo() {
}

private Companion() {
}

...
}
}

对象表达式

对象表达式实际上就是java的匿名内部类:

1
2
3
4
5
var listener = object : View.OnClickListener {
override fun onClick(p0: View?) {

}
}

它转换成的java代码如下:

1
2
3
4
OnClickListener var10000 = new OnClickListener() {
public void onClick(@Nullable View p0) {
}
};