一、内聯函數
内聯函數是指用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表達式隻能在内聯函數中或作為内聯函數的參數。