Kotlin中的object关键字

object对象

在类名前直接使用 object 关键字即可声明一个类并且自动为该类初始化一个static的实例。

  object Test {
	
	val TAG = "Test"
	
	fun test() {}
	
  }

在Kotlin代码中可以直接使用类名 Test 来访问其成员变量和方法,在Java代码中则可以通过 Test.INSTANCE 来访问其成员变量和方法。实际上在Java代码中访问 object 实例的方法暴露了其实现的原理,上述Kotlin代码编译成字节码后如下:

public final class Test {

  public final static Lcom/ocean/star/aap/Test; INSTANCE

  private final static Ljava/lang/String; TAG

  private <init>()V
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  public final getTAG()Ljava/lang/String;
    GETSTATIC com/ocean/star/aap/Test.TAG : Ljava/lang/String;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  public final test()V
    RETURN
    MAXSTACK = 0
    MAXLOCALS = 1

  static <clinit>()V
    NEW com/ocean/star/aap/Test
    DUP
    INVOKESPECIAL com/ocean/star/aap/Test.<init> ()V
    PUTSTATIC com/ocean/star/aap/Test.INSTANCE : Lcom/ocean/star/aap/Test;
    LDC "Test"
    PUTSTATIC com/ocean/star/aap/Test.TAG : Ljava/lang/String;
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 0
}

可以看到 object 对象会生成一个指定类名的类,在该类中生成一个名为 INSTANCE 的static实例,并在 clinit 方法中就初始化 INSTANCE 对象。然后生成一些static的方法来访问 INSTANCE 对象中的成员变量和方法。
在Kotlin中使用object 对象也是实现单例模式的一种便捷的方式。

companion object

在一个类中可以声明多个 object 对象,但只能声明一个 companion object 对象。

class Test {
	
   companion object CTest {
   }

   object  Test1 {
   }

   object Test2 {
   }

}

上述代码会在Test类中生成3个内部类,分别是Test$CTestTest$Test1Test$Test2 ,并且会为 Test 类生成一个 static 的CTest 实例。
这样在Kotlin中就可以直接通过类名Test来访问 CTest 中的成员变量和方法,就好像直接访问的是Test中的static成员。
对于 companion object 对象其类名 CTest 也可以省略掉,即:

class Test {
	
   companion object  {
   }

}

在省略 companion object对象类名的情况下,会自动命名为Companion,即相当于:

class Test {
	
   companion object  Companion {
   }

}

object 表达式

在Kotlin中还可以通过 object 表达式来返回一个匿名对象,使用起来就像Java中的匿名内部类。

class Test {

    view.setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View?) {
        }
    })

}

实际上编译器是生成了一个内部类 Test$1,并且该类实现了View.OnClickListener 接口,在执行到object表达式的时候则会初始化一个 Test$1 对象并返回。

posted @ 2023-08-10 01:36  jqc  阅读(153)  评论(0编辑  收藏  举报