美文网首页
7.Kotlin伴生对象及其字节码内幕详解

7.Kotlin伴生对象及其字节码内幕详解

作者: leofight | 来源:发表于2017-12-23 14:43 被阅读0次

1.类与接口

  • 示例代码
interface A {

    fun method() {
        println("A")
    }
}

open class B {
    open fun method() {
        println("B")
    }
}

class C : A, B() {
    override fun method() {
        super<A>.method()
    }
}

fun main(args: Array<String>) {
    var c = C()
    c.method()
}
  • 运行结果
A

2.抽象类

  • 示例代码
open class BaseClass {
    open fun method() {

    }
}

abstract class ChildClass : BaseClass() {
    override abstract fun method()
}

3.对象声明

object declaration,对象声明

  • 示例代码
object MyObject {
    fun method() {
        println("method")
    }
}

fun main(args: Array<String>) {
    MyObject.method()
}
  • 运行结果
method

4.伴生对象

companion object,拌生对象。
1)在Kotlin中,与Java不同的是,类是没有static方法的。
2)在大多数情况下,Kotlin推荐的做法是使用包级别的函数来作为静态方法。
3)Kotlin会将包级别的函数当作静态方法来看待。

1)如果不提供伴生对象的名字,那么编译器会提供一个默认的名字。
2)注意:虽然伴生对象的成员看起来像是Java中的静态成员,但在运行期,他们依旧是真实对象的实例成员。
3)在JVM上,可以将伴生对象的成员真正生成为类的静态方法与属性,这是通过@JcmStatic注解来实现的。
4)伴生对象在编译后会生成一个静态内部类。

  • 示例代码
class MyTest {
    companion object MyObject {

        var a: Int = 100
      
        fun method() {
            println("method invoked!")
        }

    }
}
  • 反编译结果
➜ kotlin_lecture javap com.leofight.kotlin.MyTest
Compiled from "HelloKotlin19.kt"
public final class com.leofight.kotlin.MyTest {
  public static final com.leofight.kotlin.MyTest$MyObject MyObject;
  public com.leofight.kotlin.MyTest();
  static {};
  public static final int access$getA$cp();
  public static final void access$setA$cp(int);
}
➜  kotlin_lecture javap -c com.leofight.kotlin.MyTest
Compiled from "HelloKotlin19.kt"
public final class com.leofight.kotlin.MyTest {
  public static final com.leofight.kotlin.MyTest$MyObject MyObject;

  public com.leofight.kotlin.MyTest();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #37                 // class com/leofight/kotlin/MyTest$MyObject
       3: dup
       4: aconst_null
       5: invokespecial #40                 // Method com/leofight/kotlin/MyTest$MyObject."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #42                 // Field MyObject:Lcom/leofight/kotlin/MyTest$MyObject;
      11: bipush        100
      13: putstatic     #19                 // Field a:I
      16: return

  public static final int access$getA$cp();
    Code:
       0: getstatic     #19                 // Field a:I
       3: ireturn

  public static final void access$setA$cp(int);
    Code:
       0: iload_0
       1: putstatic     #19                 // Field a:I
       4: return
}

  • 示例代码
class MyTest {
    companion object MyObject {

        var a: Int = 100
        @JvmStatic
        fun method() {
            println("method invoked!")
        }

    }
}
  • 反编译结果
➜  kotlin_lecture javap com.leofight.kotlin.MyTest   
Compiled from "HelloKotlin19.kt"
public final class com.leofight.kotlin.MyTest {
  public static final com.leofight.kotlin.MyTest$MyObject MyObject;
  public com.leofight.kotlin.MyTest();
  static {};
  public static final int access$getA$cp();
  public static final void access$setA$cp(int);
  public static final void method();
}
➜  kotlin_lecture javap -c com.leofight.kotlin.MyTest
Compiled from "HelloKotlin19.kt"
public final class com.leofight.kotlin.MyTest {
  public static final com.leofight.kotlin.MyTest$MyObject MyObject;

  public com.leofight.kotlin.MyTest();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #41                 // class com/leofight/kotlin/MyTest$MyObject
       3: dup
       4: aconst_null
       5: invokespecial #46                 // Method com/leofight/kotlin/MyTest$MyObject."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #39                 // Field MyObject:Lcom/leofight/kotlin/MyTest$MyObject;
      11: bipush        100
      13: putstatic     #19                 // Field a:I
      16: return

  public static final int access$getA$cp();
    Code:
       0: getstatic     #19                 // Field a:I
       3: ireturn

  public static final void access$setA$cp(int);
    Code:
       0: iload_0
       1: putstatic     #19                 // Field a:I
       4: return

  public static final void method();
    Code:
       0: getstatic     #39                 // Field MyObject:Lcom/leofight/kotlin/MyTest$MyObject;
       3: invokevirtual #43                 // Method com/leofight/kotlin/MyTest$MyObject.method:()V
       6: return
}

  • 示例代码
//object declaration,对象声明

object MyObject {
    fun method() {
        println("method")
    }
}

fun main(args: Array<String>) {
    MyObject.method()

    println("-----------")

    MyTest.MyObject.method()

    println("-----------")

    println(MyTest.a)
    MyTest.method()//类似静态方法,Kotlin中没有静态方法

    println("----------")

    val v = MyTest.MyObject
    println(v.javaClass)

    D.foo()
    D.bar()

    D.Companion.bar()
    D.Companion.foo()
}

//companion object,拌生对象
//在Kotlin中,与Java不同的是,类是没有static方法的。
//在大多数情况下,Kotlin推荐的做法是使用包级别的函数来作为静态方法。
//Kotlin会将包级别的函数当作静态方法来看待。

//如果不提供伴生对象的名字,那么编译器会提供一个默认的名字
//注意:虽然伴生对象的成员看起来像是Java中的静态成员,但在运行期,他们依旧是真实对象的实例成员。
//在JVM上,可以将伴生对象的成员真正生成为类的静态方法与属性,这是通过@JcmStatic注解来实现的。
//伴生对象在编译后会生成一个静态内部类。


class MyTest {
    companion object MyObject {

        var a: Int = 100
        @JvmStatic
        fun method() {
            println("method invoked!")
        }

    }
}

class D {
    companion object {
        @JvmStatic
        fun foo() {

        }

        fun bar() {

        }
    }
}


  • 运行结果
method
-----------
method invoked!
-----------
100
method invoked!
----------
class com.leofight.kotlin.MyTest$MyObject

相关文章

  • 7.Kotlin伴生对象及其字节码内幕详解

    1.类与接口 示例代码 运行结果 2.抽象类 示例代码 3.对象声明 object declaration,对象声...

  • Kotlin伴生对象及其字节码

     与Java不同的是,在kotlin中,类是没有显式的static方法和static成员变量的,都是通过伴生对象的...

  • JVM

    JVM 基础-类字节码详解 多语言编译为字节码在 JVM 运行 Java 字节码文件-- Class文件的结构属性...

  • 深入JVM内核原理-11.JVM字节码执行

    1.概要 javap 简单的字节码执行过程 常用的字节码 使用ASM生成Java字节码 JIT及其相关参数 2.j...

  • 2019-07-11

    Java字节码详解(二)字节码的运行过程 2018年10月23日 17:31:04 talex 阅读数 677 文...

  • 22. java虚拟机总结-从栈帧看字节码 (五)

    怎么查看字节码文件?字节码文件长什么样子?对象初始化之后,具体的字节码又是怎么执行的? 查看字节码的工具 java...

  • JVM笔记:i++ 和++i的字节码原理详解

    前言 一个关于i++和++i的原理详解,对字节码不太熟悉的可以先了解下字节码相关知识,因为从字节码角度更能理解两者...

  • 反射

    反射: 当一个字节码文件加载到内存的时候,jvm会对该字节码进行解剖,然后会创建一个对象的Class对象,把字节码...

  • 一些工具

    一.Java字节码查看工具:jclasslib bytecode viewer详解:https://www.cnb...

  • 反射

    反射 当一个字节码文件加载到内存的时候,jvm会对该字节码进行解剖,然后会创建一个对象的Class对象,把字节码文...

网友评论

      本文标题:7.Kotlin伴生对象及其字节码内幕详解

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