文章目录
Kotlin inline & noinline & crossinline
inline 内联函数
- Kotlin对函数进行内联的支持
- inline可以让你使用内联,即将函数内容直插到调用处,优化代码结构,减少函数类型的对象的创建
fun main() {
foo {
println("AAA")
}
}
inline fun foo(block1: () -> Unit) {
println("111")
block1()
println("333")
}
编译后等价于
public final class DemoKt {
public static final void main() {
int $i$f$foo = false;
String var1 = "111";
boolean var2 = false;
System.out.println(var1);
int var3 = false;
//block函数体开始,代码被内联了
String var4 = "AAA";
boolean var5 = false;
System.out.println(var4);
//block函数体结束
var1 = "333";
var2 = false;
System.out.println(var1);
}
// 合成方法
public static void main(String[] var0) {
main();
}
public static final void foo(@NotNull Function0 block1) {
int $i$f$foo = 0;
Intrinsics.checkNotNullParameter(block1, "block1");
String var2 = "111";
boolean var3 = false;
System.out.println(var2);
block1.invoke();
var2 = "333";
var3 = false;
System.out.println(var2);
}
}
noinline 避免参数被内联
- noinline是局部关闭内联优化
fun main() {
foo({
println("AAA")
}, {
println("BBB")
})
}
inline fun foo(block1: () -> Unit, noinline block2: () -> Unit) {
println("111")
block1()
println("222")
block2()
println("333")
}
翻译为Java代码
public final class DemoKt {
public static final void main() {
Function0 block2$iv = (Function0)null.INSTANCE;
int $i$f$foo = false;
String var2 = "111";
boolean var3 = false;
System.out.println(var2);
int var4 = false;
//block1函数体开始,代码被内联了
String var5 = "AAA";
boolean var6 = false;
System.out.println(var5);
//block1函数体结束
var2 = "222";
var3 = false;
System.out.println(var2);
//block2函数调用
block2$iv.invoke();
var2 = "333";
var3 = false;
System.out.println(var2);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
public static final void foo(@NotNull Function0 block1, @NotNull Function0 block2) {
int $i$f$foo = 0;
Intrinsics.checkNotNullParameter(block1, "block1");
Intrinsics.checkNotNullParameter(block2, "block2");
String var3 = "111";
boolean var4 = false;
System.out.println(var3);
block1.invoke();
var3 = "222";
var4 = false;
System.out.println(var3);
block2.invoke();
var3 = "333";
var4 = false;
System.out.println(var3);
}
}
局部返回
- Lambda表达式不能使用
return
关键字,可以借助内联函数使用return
- 可以利用
@
标签实现Lambda非局部返回
fun main() {
foo {
println("hello")
return
}
}
inline fun foo(block: () -> Unit) {
println("开始")
block()
println("结束")
}
//开始
//hello
fun main() {
foo {
println("hello")
return@foo
}
}
inline fun foo(block: () -> Unit) {
println("开始")
block()
println("结束")
}
//开始
//hello
//结束
crossinline
- 局部加强内联优化,避免带有
return
的Lambda产生破坏 - 被
crossinline
修饰的Lambda参数,不能使用return
不使用crossinline
fun main() {
println("1")
hello {
println("world")
return
}
println("2")
}
inline fun hello(block: () -> Unit) {
println("hello")
block()
}
//1
//hello
//world
编译后等价于
fun main() {
println("1")
println("hello")
println("world")
return
println("2")
}
使用crossinline
fun main() {
println("1")
hello {
println("world")
}
println("2")
}
inline fun hello(crossinline block: () -> Unit) {
println("hello")
block()
}
泛型参数类型具体化
- Kotlin与Java一样,由于运行时的类型擦除,导致不能直接获取一个参数的类型。
- 可以借助内联函数,内联函数会直接在字节码中生存相应的函数体实现。
inline fun <reified T> getType() {
println(T::class)
}
fun main() {
getType<Int>()
}
//class java.lang.Integer