Kotlin 扩展函数实现原理分析
Kotlin 的扩展函数非常的方便好用,支持给现有的java类增加函数,代码如下:
fun String.hello(world : String) : String {
return "hello " + world + this.length;
}
fun main(args: Array<String>) {
System.out.println("abc".hello("world"));
// 打印 hello world3
}
动机
我们就可以调用所有的 String 类型的 hello 方法,Kotlin 这么做的动机就是位替代我们的各种 Utils:FileUtils、StringUtils 等。
作用范围
大多数时候我们在顶层定义扩展,即直接在包里。
原理分析
我们可以通过编写的 Kotlin 代码反编译看看到底是怎么做到的。
- 首先通过 Android Studio 自带的工具查看字节码 搜索 Kotlin ByteCode
- 然后在生成字节码点击反编译 如图操作就可以看到我们想看的代码了
通过反编译的代码可以看出,其实 Kotlin 的扩展函数并没有修改原有的 String 类,而是在自己的类中生成了一个静态的方法,当我们在 Kotlin 中调用扩展函数时,编译器将会调用自动生成的函数并且把当前的对象(String)传入。
package com.antonioleiva.weatherapp;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 15},
bv = {1, 0, 3},
k = 2,
d1 = {"\u0000\u0014\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\u0010\u000e\n\u0002\b\u0004\u001a\u0019\u0010\u0000\u001a\u00020\u00012\f\u0010\u0002\u001a\b\u0012\u0004\u0012\u00020\u00040\u0003¢\u0006\u0002\u0010\u0005\u001a\u0012\u0010\u0006\u001a\u00020\u0004*\u00020\u00042\u0006\u0010\u0007\u001a\u00020\u0004¨\u0006\b"},
d2 = {"main", "", "args", "", "", "([Ljava/lang/String;)V", "hello", "world", "app_debug"}
)
public final class ExtensionKt {
@NotNull
public static final String hello(@NotNull String $this$hello, @NotNull String world) {
Intrinsics.checkParameterIsNotNull($this$hello, "$this$hello");
Intrinsics.checkParameterIsNotNull(world, "world");
return "hello " + world + $this$hello.length();
}
public static final void main(@NotNull String[] args) {
Intrinsics.checkParameterIsNotNull(args, "args");
System.out.println(hello("abc", "world"));
}
}
网友评论