美文网首页js css html
Kotlin : object、companion object

Kotlin : object、companion object

作者: 三十五岁养老 | 来源:发表于2022-09-05 16:50 被阅读0次

    object关键字主要有三种使用场景

    • 对象声明(object declaration)
    • 伴生对象(companion object)
    • 对象表达式(object expression)

    对象声明(object declaration)

    1. 将类的声明和定义该类的单例对象结合在一起(即通过object就实现了单例模式)
    2. 对象声明中不能包含构造器(包括主构造器和次级构造器)
    Kotlin实现及调用
    object KotlinTest {
        public var a = 0;
    }
    
    fun main() {
       var b = KotlinTest.a;
    }
    
    转成Java及调用
    public final class KotlinTest {
       @NotNull
       public static final KotlinTest INSTANCE;
    
       private KotlinTest() {
       }
    
       static {
          KotlinTest var0 = new KotlinTest();
          INSTANCE = var0;
       }
    }
    //java 调用
     public JavaTest() {
            int a = KotlinTest.INSTANCE.getA();
    
        }
    

    Kotlin 中的 object 本质上就是 Java 中简单的单例模式,同时它的构造方法是 private 的,因此 object 类不能自定义构造方法!

    伴生对象(companion object)

    在 Kotlin 中是没有 static 关键字的!想要实现通过 类名.xxx() 的方式调用工具方法,可以使用上述的 object 类,但 object 本身就是一个对象,我们无法在外部调用其构造方法,既然想拥有 object 类(通过类名调用方法)与 class 类(外部可以调用构造方法)的两种特性,这时伴生对象 companion object 就完全可以满足这个需求:

    Kotlin实现及调用
    class KotlinTest {
        companion object {
            var a = 0;
            fun test() {}
        }
        
        fun main() {
            val b: Int = KotlinTest.a;
        }
    }
    
    转成Java及调用
    public final class KotlinTest {
       private static int a;
       @NotNull
       public static final KotlinTest.Companion Companion = new KotlinTest.Companion((DefaultConstructorMarker)null); 
       public static final class Companion {
          public final int getA() {
             return KotlinTest.a;
          }
    
          public final void setA(int var1) {
             KotlinTest.a = var1;
          }
          public final void test() {
          }
          private Companion() {
          }
    
          // $FF: synthetic method
          public Companion(DefaultConstructorMarker $constructor_marker) {
             this();
          }
       }
    }
    
    //java 调用
    public class JavaTest {
        public JavaTest() {
            int a = KotlinTest.Companion.getA();
        }
    }
    

    Kotlin 中的 companion object 其实对应到 Java 中也就只是 一个静态内部类实例而已。当类中成员和伴生对象中成员重名的时候,类名调用的是伴生对象中的,实例调用的是类中的。

    对象表达式(object expression)

    对象表达式常用来作为匿名内部类的实现

    // 通过对象表达式实现点击事件回调
    btn.setOnClickListener(object : View.OnClickListener {
        override fun onClick(v: View) {
            TODO("Not yet implemented")
        }
    })
    

    @JvmField、 @JvmStatic

    在对象声明和伴生对象中,java代码调用总会跟上INSTANCE或者Companion,Kotlin 中 的伴生对象本质上就是静态实例,如果想像kotlin代码那样直接调用,需要使用kotlin自带的注解:@JvmStatic或者@JvmField

    对于对象声明
    object KotlinTest {
        @JvmField
        var a = 0;
    }
    

    转换的java代码

    public final class KotlinTest {
       @JvmField
       public static int a;
       @NotNull
       public static final KotlinTest INSTANCE;
    
       private KotlinTest() {
       }
    
       static {
          KotlinTest var0 = new KotlinTest();
          INSTANCE = var0;
       }
    }
    

    java代码中在KotlinTest类中增加了静态成员属性

    对于伴生对象
    class KotlinTest {
        companion object {
            @JvmField
            public var a = 0;
            @JvmStatic
            fun test() {
                
            }
        }
    }
    

    转换的java代码

    public final class KotlinTest {
       @JvmField
       public static int a;
       @NotNull
       public static final KotlinTest.Companion Companion = new KotlinTest.Companion((DefaultConstructorMarker)null);
    
       @JvmStatic
       public static final void test() {
          Companion.test();
       }
    
       public static final class Companion {
          @JvmStatic
          public final void test() {
          }
    
          private Companion() {
          }
    
          // $FF: synthetic method
          public Companion(DefaultConstructorMarker $constructor_marker) {
             this();
          }
       }
    }
    

    增加了对应的 static 属性和方法

    顶层函数

    fun print() {
        
    }
    class KotlinTest {
        
    }
    

    转换成Java

    public final class KotlinTest {
    }
    
    // KotlinTestKt.java
    public final class KotlinTestKt {
       public static final void print() {
       }
    }
    

    在JVM中它会生成一个类,类的名字就是你的文件名加上Kt。这个文件中的所有顶层函数编译为这个类的静态函数。因此当从Java中调用这个函数的时候和调用任何其他静态函数一样。

    要修改包含kotlin顶层函数的生成的类的名称,需要为这个文件添加@JvmName注解,将其放到文件开头,位于包名前面

    @file:JvmName("PrintUtils")
    package com.utils
    fun print() {
    
    }
    class KotlinTest {
    
    }
    

    转换成Java

    public final class KotlinTest {
    }
    // PrintUtils.java
    package com.utils;
    
    import kotlin.Metadata;
    import kotlin.jvm.JvmName;
    @JvmName(
       name = "PrintUtils"
    )
    public final class PrintUtils {
       public static final void print() {
       }
    }
    

    单例

    class KotlinTest {
        private constructor() {
    
        }
        companion object {
            val instance:KotlinTest by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
               KotlinTest()
           }
        }
    }
    

    相关文章

      网友评论

        本文标题:Kotlin : object、companion object

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