美文网首页KotlinKotlin语言
Kotlin伴生对象及其字节码

Kotlin伴生对象及其字节码

作者: 跳动的字符 | 来源:发表于2018-05-05 21:03 被阅读0次

     与Java不同的是,在kotlin中,类是没有显式的static方法和static成员变量的,都是通过伴生对象的形式间接提供的。下面来谈谈Kotlin中的伴生对象。

     1. 对象声明,object declaration,如下所示:

    object MyObject {
        fun method() {
            println("MyObject method")
        }
    }
    
    fun main(args: Array<String>) {
        MyObject.method()
    }
    

     2. 伴生对象,companion object,

    • 在大多数情况下,kotlin推荐的做法是使用包级别的函数来作为静态方法,kotlin会将包级别的函数当作静态方法来看待;
    • 在kotlin中,一个类中只能有一个伴生对象,伴生对象的名字可以省略,如果省略(不提供伴生对象的名字),那么编译器会提供一个默认的名字Companion。如下所示:
    class MyCompanion {
    
        companion object MyObject {
    
            var a:Int = 100
    
            @JvmStatic
            fun method() {
                println("method invoked")
            }
        }
    }
    
    fun main(args: Array<String>) {
        MyCompanion.MyObject.method() // 演示用,实际会省略MyObject
        println("--------------")
    
        println(MyCompanion.a)
        MyCompanion.method() // 类似于静态方法,kotlin中没有静态方法
        println("--------------")
    
        println(MyCompanion.javaClass)
    }
    

    注意:

    • 虽然伴生对象的成员看起来像是Java中的静态成员,但在运行期它们依旧是真实对象的实例成员;
    • 在JVM上,可以将伴生对象的成员真正生成为类的静态方法和属性,这是通过@JvmStatic注解实现的;
    • 伴生对象在编译后会生成一个静态内部类。

     利用javap命令对伴生对象MyCompanion反编译后的结果如下:

    ➜  kotlin-lecture javap com.ssy.kotlin.MyCompanion
    Compiled from "HelloKotlin19.kt"
    public final class com.ssy.kotlin.MyCompanion {
      public static final com.ssy.kotlin.MyCompanion$MyObject MyObject;
      public com.ssy.kotlin.MyCompanion();
      static {};
      public static final int access$getA$cp();
      public static final void access$setA$cp(int);
      public static final void method();
    }
    

    通过上面的结果可以看出,加了@JvmStatic注解,会出现一个static的method()方法。
    下面将@JvmStatic注解注释掉后,重新用javap进行反编译,结果如下:

    ➜  kotlin-lecture javap com.ssy.kotlin.MyCompanion
    Compiled from "HelloKotlin19.kt"
    public final class com.ssy.kotlin.MyCompanion {
      public static final com.ssy.kotlin.MyCompanion$MyObject MyObject;
      public com.ssy.kotlin.MyCompanion();
      static {};
      public static final int access$getA$cp();
      public static final void access$setA$cp(int);
    }
    

    通过上面的结果可以看出,@JvmStatic注解注释后,static的method()方法没有了。
    从上面可以得出结论:伴生对象中的方法上加与不加@JvmStatic,对程序调用上(对使用者)是没有任何影响的,只是在底层的字节码形式上存在明显的差别。

    好了,就先写到这里。

    相关文章

      网友评论

        本文标题:Kotlin伴生对象及其字节码

        本文链接:https://www.haomeiwen.com/subject/idserftx.html