Kotlin 中的伴随对象与包级函数

522 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

Kotlin 中的伴随对象与包级函数

伴生对象的语法上类似于Java中的静态方法。因此我们在很多时候将它用于相同的目的。下面我们将了解下伴生对象的工作原理,以及在 Kotlin 中创建静态方法的推荐方法。

伴生对象

类中的对象声明可以用companion关键字标记。从语法上讲,它类似于 Java 中的静态方法:您使用对象的类名作为限定符来调用对象成员。

class XCompaint {
    companion object{
        fun printString(){
            print("ss")
        }
    }
}
fun main() {
    XCompaint.printString()
}

下面我们通过反编译之后的Java代码来看,Java底层是怎么完成的

public final class XCompaint {
   @NotNull
   public static final XCompaint.Companion Companion = new XCompaint.Companion((DefaultConstructorMarker)null);

   )
   public static final class Companion {
      public final void printString() {
         String var1 = "ss";
         System.out.print(var1);
      }
      private Companion() {
      }

      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

可以看出它会在类的内部将伴生对象使用静态内部类的方式实现,并且创建一个静态内部类的实例,我们在调用伴生类中的方法都是通过访问静态内部类的实例进行伴生类中的方法访问。可以看出这是一种伪静态的方式,如果存在Java和Kotlin互调,Java中就没办法访问到伴生对象中的成员,如果我们需要实现真正的静态,我们可以使用Kotlin中的顶层方法和JvmStatic注解

  • @JvmStatic 注解只能加在单例类或 companion object 中的方法上,如果加在一个普通方法上,会直接提示语法错误。
class XCom {
    companion object{
        @JvmStatic
        fun printString(){
            print("sss")
        }
    }
}

这样我们就可以在Java中访问Kotlin中的伴生对象的成员

顶层函数

顶层函数是Kotlin中不会定义在任何类中的方法,我们在Kotlin中可以全局访问顶层函数,Kotlin会将顶层方法全部编译成静态方法

fun printString(){
    print("顶层函数")
}

然后我们通过反编译之后看以下java的实现代码是怎么样的

public final class XComKt {
   public static final void printString() {
      String var0 = "顶层函数";
      System.out.print(var0);
   }
}

可以看到反编译的之后的Java代码就是我们平常编写静态方法的写法。编译器在编译时会将文件名加上Kt作为类名,这样我们就可以在Java中去调用

public class Demo {
    public static void main(String[] args) {
        XComKt.printString();
    }
}

所以在Java中需要实现真正的静态方法,比较推荐使用顶层函数的方式。