Kotlin中的扩展函数和扩展属性
扩展函数
Kotlin中可以给一个类额外添加这个类中没有的函数,即扩展函数。例如:
fun Int.dp2px(context: Context) {
	TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics)
}
fun test () {
	println(16.dp2px())
}
上述代码给Int类添加了一个扩展函数dp2px用于将dp转成px,在代码中可以直接对Int类型的变量调用dp2px函数,就好像Int类的其他固有函数一样。在扩展函数中可以通过this访问调用扩展函数的变量本身。
需要注意的是,扩展函数的调用者类型是静态声明的类型,而不是实际的运行时类型,例如:
fun Context.toString() : String {
	return "context"
}
fun Activity.toString() : String {
	return "activity"
}
fun printContext(context: Context) {
	println(context.toString())
}
fun test(activity: Activity) {
	printContext(activity)
}
上述代码调用test函数输出的结果是"context"而不是"activity"
扩展属性
Kotlin中还可以给一个类额外添加这个类中没有的属性,即扩展属性。例如:
val View.activity : Activity?
	get() = this.context as? Activity
上述代码给View类添加了一个扩展属性activity,扩展属性并不是真的给该类添加了一个属性,所以只能通过getter和setter来访问和初始化
扩展函数和扩展属性的原理
class Test {
    fun Int.dp2px(context: Context) {
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), context.resources.displayMetrics)
    }
    val View.activity : Activity?
        get() = this.context as? Activity
}
通过将上述Kotlin代码转成字节码再反编译后如下:
public final class Test {
   public final void dp2px(int $this$dp2px, @NotNull Context context) {
      Intrinsics.checkNotNullParameter(context, "context");
      float var10001 = (float)$this$dp2px;
      Resources var10002 = context.getResources();
      Intrinsics.checkNotNullExpressionValue(var10002, "context.resources");
      TypedValue.applyDimension(1, var10001, var10002.getDisplayMetrics());
   }
   @Nullable
   public final Activity getActivity(@NotNull View $this$activity) {
      Intrinsics.checkNotNullParameter($this$activity, "$this$activity");
      Context var10000 = $this$activity.getContext();
      if (!(var10000 instanceof Activity)) {
         var10000 = null;
      }
      return (Activity)var10000;
   }
}
可以发现扩展函数和扩展属性的原理是在编译后生成了特定的函数,并将扩展类型的对象作为第一个参数传递进去。
对于Int类型的扩展函数dp2px实际是在Test类中生成一个dp2px函数,并接收Int类型的参数$this$dp2px作为第一个参数。
对于View类型的扩展属性activity实际是在Test类中生成一个getActivity函数,并接收View类型的参数$this$activity作为第一个参数
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号