本文重点:
- 什么是内联,如何声明为内联函数,内联的应用场景,内联的底层实现原理,如何在IDEA中查看Kotlin程序对应的Java代码,什么是函数引用,函数引用的应用场景与具体使用;
前置知识铺垫:
-
Kotlin文件最终会编译为 Java文件后执行
-
在IDEA中如何 查看Kotlin对应的 Java代码
-
第一步:获取Kotlin对应的字节码文件
-
第二步:将字节码文件转成 Java代码(点击反编译按钮)
-
即可查看Kotlin原文件与对应的 Java文件
-
本文概述:当函数参数为Lamda,尽量使用inline
-
什么是内联:函数A作为函数B的参数
-
什么情况下使用内联:函数参数为Lamda表达式
-
如何使用内联:
public inline fun function(){ } -
内联的使用细节:在内联函数中不能调用非public修饰的函数
内联实现原理:类似于C++中的define
-
在编译期做了代码替换
- 对比使用inline前后反编译得到的 Java代码
-
在调用处不存在任何的函数开辟,对象开辟;
-
原函数的Lamda参数依然是转成了Function
-
为什么要引入内联:降低性能损耗、减少了在调用出存在对象开辟与调用
-
原始代码:Kotlin
package step2 //函数内联学习 //模拟数据库 const val USER_MAME = "WAsbry" const val USER_PWD = "123" //模仿前端作数据的校验:第三个参数为Lamda public fun loginAPI(username:String,userpwd:String,responseResulut:(String,Int) -> Unit){ //做简单校验 if(username == null || userpwd == null){//TODO 信息为空终止程序 } //调用服务端API if(webServiceLoginAPI(username,userpwd)){ responseResulut("Login success",200) }else{ responseResulut("Login error",444) } } //模仿服务端 private fun webServiceLoginAPI(name:String,pwd:String) : Boolean{ // return if(name == USER_MAME && pwd == USER_PWD)return true else return false return name == USER_MAME && pwd == USER_PWD } fun main(){ loginAPI("WAsbry","123"){msg:String,code:Int-> println("登录结果为:msg:$msg,code:$code") } } -
反编译后main函数结果:在调用处会创建对象(instance)
-
-
使用函数内联后:
-
源代码:
package step2 //函数内联学习 //模拟数据库 const val USER_MAME = "WAsbry" const val USER_PWD = "123" //模仿前端作数据的校验 public inline fun loginAPI(username:String,userpwd:String,responseResulut:(String,Int) -> Unit){ //做简单校验 if(username == null || userpwd == null){//TODO 信息为空终止程序 } //调用服务端API if(webServiceLoginAPI(username,userpwd)){ responseResulut("Login success",200) }else{ responseResulut("Login error",444) } } //模仿服务端 fun webServiceLoginAPI(name:String,pwd:String) : Boolean{ return name == USER_MAME && pwd == USER_PWD } fun main(){ loginAPI("WAsbry","123"){msg:String,code:Int-> println("登录结果为:msg:$msg,code:$code") } } -
反编译后的 Java文件:不存在对象的使用,但lamda 参数依旧会被编译为接口
-
扩招知识:Kotlin中的函数引用
-
概述:
- 是什么:函数类型的对象
- 应用场景:配合inline处理函数参数为Lamda表达式
-
技巧:可以使用一个单独的对象存放函数引用,在调用处扔进去就行了
val method = ::verify -
代码展示:
package step2 //函数引用 const val NAME = "WAsbry" const val PWD = "123" fun main(){ login("WAsbry","123",::verify) } fun verify(msg: String,code: Int){ println("登录结果为:msg--->$msg,code--->$code") } inline fun login(name: String,pwd: String,responseResult: (name: String,code: Int) ->Unit) { if(name == NAME && pwd == PWD){ responseResult("登录成功",200) }else{ responseResult("登录失败",444) } }