object
首先来看一段object修饰的代码:
object TestObject {
fun test(){
}
}
接着看看这段代码对应的字节码
package com.lexin.gamebox.ui.mall.view;
import kotlin.Metadata;
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
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/lexin/gamebox/ui/mall/view/TestObject;", "", "()V", "test", "", "app_debug"}
)
public final class TestObject {
public static final TestObject INSTANCE;
public final void test() {
}
private TestObject() {
}
static {
TestObject var0 = new TestObject();
INSTANCE = var0;
}
}
可以看到这是一个饿汉式的单例,一开始就创建了对象。object可以单独创建,作用域为整个类,里面的成员和方法,可以直接通过object类来调用。由此我们再来看一下object的其他用法:
对象表达式
继承一个匿名对象
val textView = findViewById<TextView>(R.id.tv)
textView.setOnClickListener(object : OnClickListener {
override fun onClick(p0: View?) {
Toast.makeText(this@TestActivity, "点击事件生效", Toast.LENGTH_LONG)
}
})
对象声明
用object 修饰的类为静态类,里面的方法和变量都为静态的。
直接声明类
直接声明类
object DemoManager {
private val TAG = "DemoManager"
fun a() {
Log.e(TAG,"此时 object 表示 声明静态内部类")
}
}
声明静态内部类
类内部的对象声明,没有被inner 修饰的内部类都是静态的
class DemoManager{
object MyObject {
fun a() {
Log.e(TAG,"此时 object 表示 直接声明类")
}
}
}
companion object
同样,先来看下源码:
class Test {
var field: String = "haha";
companion object A{
fun testCompanionObject(){
}
}
再来看看转成字节码后的样子:
package com.lexin.gamebox.ui.mall.view;
import kotlin.Metadata;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 1,
d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"},
d2 = {"Lcom/lexin/gamebox/ui/mall/view/Test;", "", "()V", "A", "app_debug"}
)
public final class Test {
@NotNull
private static String field = "haha";
public static final Test.A A = new Test.A((DefaultConstructorMarker)null);
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 1,
d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0005\n\u0002\u0010\u0002\n\u0000\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\t\u001a\u00020\nR\u001a\u0010\u0003\u001a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\"\u0004\b\u0007\u0010\b¨\u0006\u000b"},
d2 = {"Lcom/lexin/gamebox/ui/mall/view/Test$A;", "", "()V", "field", "", "getField", "()Ljava/lang/String;", "setField", "(Ljava/lang/String;)V", "testCompanionObject", "", "app_debug"}
)
public static final class A {
@NotNull
public final String getField() {
return Test.field;
}
public final void setField(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
Test.field = var1;
}
public final void testCompanionObject() {
}
private A() {
}
// $FF: synthetic method
public A(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
可以看到A变成静态的类,A中的成员变量filed和成员方法testCompanionObject都变成了final static。companion object只能定义在class中,并且一个class中只能定一个一个companion object。companion object作用域为代码块,里面成员和方法可通过companion object直接调用(companion object会生成一个companion对象)
JvmStatic
JvmStatic 定义静态方法,只能在object或者companion object里使用
网友评论