選擇)
const val是 Kotlin 里最簡(jiǎn)單的一個(gè)關(guān)鍵字,也是最容易暴露"只用過(guò)、沒(méi)理解"的點(diǎn)。面試?yán)飭?wèn)"編譯期常量是什么意思",能答"編譯時(shí)直接替換、不進(jìn)內(nèi)存"是及格;能答清二進(jìn)制兼容的坑才是高分——而那個(gè)坑在真實(shí)項(xiàng)目里造成過(guò)線上事故。先把結(jié)論放在前面:const val的值在編譯期被內(nèi)聯(lián)進(jìn)每個(gè)使用點(diǎn),編譯產(chǎn)物里不保留這個(gè)字段。由此推出一條關(guān)鍵結(jié)論:它不是二進(jìn)制兼容的——一旦某個(gè)庫(kù)里的const常量值發(fā)生變化,依賴方即使不重新編譯,運(yùn)行時(shí)拿到的也還是舊值(因?yàn)榕f值已經(jīng)內(nèi)聯(lián)進(jìn)它的字節(jié)碼了)。這與 Java 的static final恰好相反,是這一題最值得講清楚的地方。機(jī)制背后的執(zhí)行路徑先看編譯結(jié)果的差異。假設(shè)有這樣一個(gè)常量:object ApiConfig { const val BASE_URL = "https://api.v1.com" val RUNTIME_URL = getUrlFromServer() // 非 const,是運(yùn)行時(shí)初始化 }const val的處理流程是:編譯器解析源碼時(shí)求值(必須是編譯期可確定的字面量或常量表達(dá)式),把字面量直接寫(xiě)進(jìn)每個(gè)引用點(diǎn)的字節(jié)碼常量池。字節(jié)碼里沒(méi)有ApiConfig.BASE_URL這個(gè)字段,