一、内联函数
内联函数是指用inline关键字修饰的函数。 在类内定义的函数被默认成内联函数。 内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。 内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。
二、Java中的内联函数
在java中不能显式地声明函数内联,只能间接通过JVM虚拟机实现。可以通过两种方式向虚拟机提出请求,一种是使用final修饰:
public final void a(){
statement
}
- 1
- 2
- 3
一种是把方法修饰为private
private void b(){
statement
}
- 1
- 2
- 3
但是即使添加了这些标志,虚拟机也不一定会把方法内联化,具体表现由虚拟机决定。
内联的优点:减少函数栈调用成本。
内联的缺点:代码变长,占用更多内存空间和指令缓存。
三、Kotlin与内联函数
Kotlin作为一种立志于替代java的语言,相较于java更多地使用了内联函数这种特性以优化语言的编程表现。
如Kotlin标准库中提供的let,apply函数:
public inline fun <T> (block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
集合库中创建可变list的mutableListOf函数:
public inline fun <T> mutableListOf(): MutableList<T> = ArrayList()
- 1
它们具有一个非常明显的共同点,就是这些方法都会被频繁调用。对频繁调用的代码内联化,可以提高代码效率降低调用成本。
在Kotlin中内联函数需要指定inline关键字,是显式声明的,被声明的函数都会被内联化。Kotlin的内联是编译器实现的,可能会生成较多代码,但不会对运行期性能有影响。
四、Kotlin的非内联
有的时候只需要内联部分lamda参数,则可以通过noinline关键字修饰非内联参数,比如:
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) {
statement
}
- 1
- 2
- 3
内联lamda表达式只能在内联函数中或作为内联函数的参数。