Kotlin Extension — Properties&Companion

方法可以有装饰者模式,那属性呢?
当然可以!

实例属性

考虑实例属性的这样一个例子:

在Parent.kt中声明一个value的变量并赋值为1,并在Other.kt中使用Properties Extension
class Parent {
    val value : Int = 1
}
class Other

val Parent.value : Int
        get() = 0
经过kotlinc的编译(编译过程中同样会有warning),反编译OtherKt.class 文件:
Compiled from "Other.kt"
public final class com.maxtropy.viewtest.OtherKt {
  public static final int getValue(com.maxtropy.viewtest.Parent);
    Code:
       0: aload_0
       1: ldc           #9                  // String $receiver
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
       6: iconst_0
       7: ireturn
}

哇!OtherKt中多了一个getValue()方法诶!他在唯一入参是Parent,这意味着:

  • 后面如果在kt文件中访问Parent实例的value变量,最终都是访问的这个方法!
  • 在同一个Other.kt中,对同一个类的同一个属性,只能使用一次Extension (用两次还没编译呢,IDE就直接先报Error了靓仔!)

Companion Object

同样跟上面的例子,只不过我们将value声明在Parent的companion object中,在Other中执行Parent.Companion.value的Extension

val Parent.Companion.value
        get() = 99

编译结果跟普通的Properties Extension近乎一致:

Compiled from "Other.kt"
public final class com.maxtropy.viewtest.OtherKt {
  public static final int getValue(com.maxtropy.viewtest.Parent$Companion);
    Code:
       0: aload_0
       1: ldc           #9                  // String $receiver
       3: invokestatic  #15                 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
       6: bipush        99
       8: ireturn
}

最大的区别便是唯一入参类型变成了Parent$Companion
值得我们注意的是,最后入栈的常量(代码中最后返回的常量数)并不像上面是一个int型常量,而是一个byte型常量。想必是kotlinc在编译过程中自动优化了

你可能感兴趣的:(Kotlin Extension — Properties&Companion)