一、内联函数

内联函数是指用inline关键字修饰的函数。 在类内定义的函数被默认成内联函数。 内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。 内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。

二、Java中的内联函数

在java中不能显式地声明函数内联,只能间接通过JVM虚拟机实现。可以通过两种方式向虚拟机提出请求,一种是使用final修饰

public final void a(){
    statement
}

一种是把方法修饰为private

private void b(){
    statement
}

但是即使添加了这些标志,虚拟机也不一定会把方法内联化,具体表现由虚拟机决定。
内联的优点:减少函数栈调用成本。
内联的缺点:代码变长,占用更多内存空间和指令缓存。

三、Kotlin与内联函数

Kotlin作为一种立志于替代java的语言,相较于java更多地使用了内联函数这种特性以优化语言的编程表现。
如Kotlin标准库中提供的let,apply函数:

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

集合库中创建可变list的mutableListOf函数:

public inline fun <T> mutableListOf(): MutableList<T> = ArrayList()

它们具有一个非常明显的共同点,就是这些方法都会被频繁调用。对频繁调用的代码内联化,可以提高代码效率降低调用成本。
在Kotlin中内联函数需要指定inline关键字,是显式声明的,被声明的函数都会被内联化。Kotlin的内联是编译器实现的,可能会生成较多代码,但不会对运行期性能有影响。

四、Kotlin的非内联

有的时候只需要内联部分lamda参数,则可以通过noinline关键字修饰非内联参数,比如:

inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) {  
  statement  
}

内联lamda表达式只能在内联函数中或作为内联函数的参数。