文章目录
- 一、内联函数
- 1、Lambda 表达式弊端
- 2、" 内联 " 机制避免内存开销
- 3、内联函数本质 - 编译时宏替换
- 4、内联函数不能递归
- 二、普通函数代码示例
- 三、内联函数代码示例
一、内联函数
1、Lambda 表达式弊端
Lambda 表达式弊端 :
Lambda 表达式 的 灵活使用 , 是以 牺牲内存开销为代价的 ;
在 Java 虚拟机中 , Lambda 表达式 是以 实例对象 的形式 , 存储在堆内存中的 , 这就产生了内存开销 ;
2、" 内联 " 机制避免内存开销
" 内联 " 机制避免内存开销 :
在 Kotlin 语言中提供了一种 " 内联 " 机制 ,
解决了上面的 Lambda 表达式的 内存开销 问题 ,
将 使用 Lambda 表达式 作为参数的函数 定义为 inline 内联函数 ,
Java 虚拟机就 不会再为 lambda 表达式 在堆内存中 创建 实例对象 了 ,
这样就 避免了 Lambda 表达式 的内存开销 ;
3、内联函数本质 - 编译时宏替换
内联函数使用 :
在使用 Lambda 表达式的时候 ,
Kotlin 编译器直接将 inline 内联函数 的 函数体 直接拷贝到 使用位置 ;
内联函数 类似于 C 语言中的 预编译指令 宏定义 , 在编译时直接替换拷贝宏定义内容 ;
Kotlin 中的 内联函数 也是一种 编译时 进行 宏替换的操作 ;
4、内联函数不能递归
内联函数不能递归 :
如果 将函数 定义为 内联函数 ,
则该函数 不能进行递归操作 ,
递归操作 会导致 函数体的 无限复制粘贴 ,
编译器会报警 ;
二、普通函数代码示例
代码示例 : 下面的代码中 studentDoSomething
是普通函数 ;
fun main() {
// 定义函数类型变量, 之后作为函数参数传递给函数
val actionFun = { name: String, age: Int ->
"student $name $age years old, say hello"
}
// 调用 studentDoSomething 函数, 输入姓名, 年龄, 执行的操作
studentDoSomething("Tom", 18, actionFun);
}
fun studentDoSomething(name: String, age: Int,
action: (String, Int) -> String) {
val act = action(name, age);
println(act)
}
将字节码转换为 Java 代码内容如下 :
代码语言:javascript复制import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 2,
d1 = {"u0000u001cnu0000nu0002u0010u0002nu0002bu0002nu0002u0010u000enu0000nu0002u0010bnu0000nu0002u0018u0002nu0000u001au0006u0010u0000u001au00020u0001u001a0u0010u0002u001au00020u00012u0006u0010u0003u001au00020u00042u0006u0010u0005u001au00020u00062u0018u0010u0007u001au0014u0012u0004u0012u00020u0004u0012u0004u0012u00020u0006u0012u0004u0012u00020u00040b¨u0006t"},
d2 = {"main", "", "studentDoSomething", "name", "", "age", "", "action", "Lkotlin/Function2;", "KotlinDemo"}
)
public final class HelloKt {
public static final void main() {
Function2 actionFun = (Function2)null.INSTANCE;
studentDoSomething("Tom", 18, actionFun);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
public static final void studentDoSomething(@NotNull String name, int age, @NotNull Function2 action) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(action, "action");
String act = (String)action.invoke(name, age);
boolean var4 = false;
System.out.println(act);
}
}
三、内联函数代码示例
代码示例 : 下面的代码中 studentDoSomething
是内联函数 ;
fun main() {
// 定义函数类型变量, 之后作为函数参数传递给函数
val actionFun = { name: String, age: Int ->
"student $name $age years old, say hello"
}
// 调用 studentDoSomething 函数, 输入姓名, 年龄, 执行的操作
studentDoSomething("Tom", 18, actionFun);
}
inline fun studentDoSomething(name: String, age: Int,
action: (String, Int) -> String) {
val act = action(name, age);
println(act)
}
将字节码转换为 Java 代码内容如下 :
代码语言:javascript复制import kotlin.Metadata;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 2,
d1 = {"u0000u001cnu0000nu0002u0010u0002nu0002bu0002nu0002u0010u000enu0000nu0002u0010bnu0000nu0002u0018u0002nu0000u001au0006u0010u0000u001au00020u0001u001a3u0010u0002u001au00020u00012u0006u0010u0003u001au00020u00042u0006u0010u0005u001au00020u00062u0018u0010u0007u001au0014u0012u0004u0012u00020u0004u0012u0004u0012u00020u0006u0012u0004u0012u00020u00040bHu0086b¨u0006t"},
d2 = {"main", "", "studentDoSomething", "name", "", "age", "", "action", "Lkotlin/Function2;", "KotlinDemo"}
)
public final class HelloKt {
public static final void main() {
Function2 actionFun = (Function2)null.INSTANCE;
String name$iv = "Tom";
int age$iv = 18;
int $i$f$studentDoSomething = false;
String act$iv = (String)actionFun.invoke(name$iv, Integer.valueOf(age$iv));
boolean var5 = false;
System.out.println(act$iv);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
public static final void studentDoSomething(@NotNull String name, int age, @NotNull Function2 action) {
int $i$f$studentDoSomething = 0;
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(action, "action");
String act = (String)action.invoke(name, age);
boolean var5 = false;
System.out.println(act);
}
}