美文网首页
Kotlin-Object关键字作用

Kotlin-Object关键字作用

作者: 杨0612 | 来源:发表于2022-03-31 16:25 被阅读0次
    Object关键字使用场景:匿名内部类、单例、伴生对象。
    匿名内部类

    Kotlin匿名内部类定义使用跟Java类似,如何定义这里就不多赘述了。

    不过它有一个增强的点,Java的匿名内部类不能再继承接口,而Kotlin可以。

    以下匿名内部类在实现I1接口的基础上,再实现I2、 I3两个接口,相当于增强能力。被监听者根据不同场景进行回调,例如某场景只需要回调I1,某场景需要回调I2、I3。

    Java要实现此功能,需要定义一个内部类,Kotlin会比较灵活一些。

        fun test() {
            val listener = object : I1, I2, I3 {
                override fun onSuccess1() {}
                override fun onSuccess2() {}
                override fun onSuccess3() {}
            }
            setListener(listener)
        }
        private fun setListener(listener: I1) {
            //dosomething
            listener.onSuccess1()
            if (listener is I2) {
                listener.onSuccess2()
            }
            if (listener is I3) {
                listener.onSuccess3()
            }
    }
    
    单例

    Kotlin实现单例是非常简单的,只要用object描述类名即可。

    object A {
         fun test(){}
    }
        
    //反编译代码
    public final class A {
       @NotNull
       public static final A INSTANCE;
       public final void test() {}
       private A() {}
    
       static {
          A var0 = new A();
          INSTANCE = var0;
       }
    }
    

    看了下反编译的代码,原来是在类A初始化的时候就创建实例了。

    不过这种方式有两个问题

    1. 可能会浪费性能,因为在没有使用就已经创建了;
    2. 无法传入参数,对于Android平台是很不友好的。
    伴生对象

    伴生对象是类中的静态对象,只能内部实例化且只有一个,可以用来定义类的静态变量、函数。

    class A {
        companion object {
            const val name: String = "A"//1
            fun getInstance(): A {//2
                return A()
            }
        }
    }
    
    • 注释1,定义了静态变量name;
    • 注释2,定义了静态方法getInstance获取实例对象;

    反编译看看

    public final class A {
       @NotNull
       public static final String name = "A";//1
       @NotNull
       public static final A.Companion Companion = new A.Companion();//2
    
       public static final class Companion {//3
          @NotNull
          public final  A getInstance() {//5
             return new A();
          }
          private Companion() {//4
          }
    
          public Companion(DefaultConstructorMarker $constructor_marker) {//6
             this();
          }
       }
    }
    
    • 注释1,对应companion object{}中定义的静态变量name;
    • 注释2、3、4,定义了静态内部类Companion,且构造函数是私有,A实例化了静态变量Companion;
    • 注释5,对应companion object{}中定义的静态函数getInstance;
    • 注释6,虽然也定义了public构造函数,但观察入参类型得知,该构造函数只能是编译器调用,而我们开发者是无法调用的。
      所以我们知道,Kotlin的companion object{},是对应一个对象,也叫伴生对象,
      该对象类会描述我们定义的静态函数(静态变量好像不属于该类)。
    一个有意思的细节
    class A {
        companion object {
            const val name: String = "A"
            @JvmStatic//1
            fun getInstance(): A {
                return A()
            }
        }
    }
    
     //加注解前,Java调用
      B.Companion.getInstance();
     //加注解后,Java调用
     B.getInstance();
    
    • 注释1:增加@JvmStatic注解是为了方便Java调用,那么反编译以后A中会增加定义getInstance函数,不过其内部还是调用伴生对象的getInstance。
      大家可以反编译看看。

    以上分析有不对的地方,请指出,互相学习,谢谢哦!

    相关文章

      网友评论

          本文标题:Kotlin-Object关键字作用

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