Kotlin基本语法: 静态成员与companion伴生对象
Kotlin的静态实现
在Java中可以通过static关键字声明静态的属性或方法。但是在Kotlin中并没有延续这个关键字,而是使用伴生对象实现,在class内部声明一个companion object代码块,其内部的成员变量和方法都将被编译为静态的。
class TestStatic { //伴生对象 companion object Factory { val str: String = "" fun create(): TestStatic { println(this) return TestStatic() } } } 复制代码
Factory为最终生成的静态内部类类名,通常来说Factory名字可以省略,如果省略,类名为默认的Companion。
调用方法,就跟调用一个静态方法一样类名+方法名。
TestStatic.create() 复制代码
静态代码块
Kotlin中的也可写静态代码块,只需在companion object
中嵌套一个init代码块。
companion object { //静态代码块 init { val a = "adc" } } 复制代码
反编译代码后可以看到与java中的写法一致。
static { String var0 = "adc"; } 复制代码
与内部object类的区别
通过反编译我们可以看一下其内部实现。
public final class TestStatic { //静态成员变量 private static final String str = ""; public static final TestStatic.Factory Factory = new TestStatic.Factory(); public static final class Factory { @NotNull public final String getStr() { return TestStatic.str; } @NotNull public final TestStatic create() { System.out.println(this); return new TestStatic(); } private Factory() { } } } 复制代码
是不是感觉和上一篇讲的object类有点像?其实还真是挺像的,因为就差一个关键字,我们把companion关键字去掉,重新反编译对比一下。
class TestStatic { object Factory { val str: String = "" fun create(): TestStatic { println(this) return TestStatic() } } } 复制代码
反编译结果:
public final class TestStatic { public static final class Factory { //成员变量声明在内部类中 private static final String str = ""; public static final TestStatic.Factory INSTANCE; @NotNull public final String getStr() { return str; } @NotNull public final TestStatic create() { System.out.println(this); return new TestStatic(); } private Factory() { } static { TestStatic.Factory var0 = new TestStatic.Factory(); INSTANCE = var0; str = ""; } } } 复制代码
通过代码的比较发现了明显的区别,虽然两者最终都会生成一个静态内部类,但companion object代码块中的成员变量最终会被声明到外部类中,也这是为什么我们能通过外部类名直接访问,而object类则需要用外部类.内部类的方式调用。
//object类调用方式 TestStatic.Factory.create() //companion object代码块使用方式 TestStatic.create();//编译器会我们自动补全为TestStatic.Factory.create() 复制代码
注意事项
companion object : Comparable { override fun compareTo(other: String): Int { //支持比较 } }