我們先看看kotlin官方文檔的解釋
-
val 聲明一個
只讀屬性(也稱作只讀變量)
或局部變量
- 如果被聲明的變量是方法內(nèi)部的局部變量艾恼,可以稱為
常量
- 如果被聲明變量是頂級變量二跋,稱為
只讀變量
- 如果被聲明的變量是方法內(nèi)部的局部變量艾恼,可以稱為
-
const 將屬性標(biāo)記為編譯期常量
(編譯期常量是在程序編譯期會替換成字面量)
- 位于頂層或者是
object
聲明 或companion object
的一個成員 - 以 String 或原生類型值初始化
- 沒有自定義
getter
- 位于頂層或者是
我們通過代碼一一理解一下
- 局部變量
fun main() {
val params = 0
params
println("params: $params")
}
局部變量中,我們無法實現(xiàn)params
的 get()
方法缩挑, const
要求也不滿足但两,所以無法被const
標(biāo)記,也無法重新分配值供置,此時我們可以把val params = 0
看做是常量
那是不是所有被val
修飾的就是常量呢谨湘?這就引出我們的重點只讀變量了
,我們在一開始說過被val聲明變量是頂級變量芥丧,稱為只讀變量
- 只讀變量
val params
get() = Math.random()
fun main() {
println("params - $params")
}
如上代碼紧阔,我們每運行一次,得到的結(jié)果值都不一樣续担,原因就在這個get擅耽,我們可以通過get()賦值,此時他就不是一個常量物遇,而是一個只能讀取不能寫入的變量了
那kotlin的常量如何定義呢乖仇?
kotlin中聲明常量有兩種方式: const val
以及 @JvmFiled val
- const
const val params = 0
fun main() {
println("params - $params")
}
我們看看生成的java代碼如下
public final class AAAAAKt {
public static final int params = 0;
public static final void main() {
String var0 = "params - 0"; //變動1處
boolean var1 = false;
System.out.println(var0);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
const修飾的常量必須是top-level(top-level是屬于文件內(nèi)部,不在類中定義
)以及object 聲明 或 companion object 的一個成員
- @JvmField
@JvmField val params = 0
fun main() {
println("params - $params")
}
同樣看看生成的Java代碼如下
public final class AAAAAKt {
@JvmField
public static final int params = 0;
public static final void main() {
String var0 = "params - " + params; //變動1處
boolean var1 = false;
System.out.println(var0);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
從上述兩處Java源碼可以看出询兴,const
和@JvmField
還是有區(qū)別的乃沙,具體如下改動
// const val
public static final int params = 0;
public static final void main() {
String var0 = "params - 0";//[1]
boolean var1 = false;
System.out.println(var0);
}
// @JvmField val
@JvmField
public static final int params = 0;
public static final void main() {
String var0 = "params - " + params;//[2]
boolean var1 = false;
System.out.println(var0);
}
上述兩處代碼比較可以看出,主要區(qū)別是被const
標(biāo)示的常量值[1]
實現(xiàn)了內(nèi)聯(lián)诗舰,而@JvmField
注釋的常量[2]
則沒有
總結(jié):
- 1: val修飾局部變量可以被當(dāng)做是
常量
- 2: val修飾
靜態(tài)類或伴生對象的字段
時只能稱作只讀變量
- 3: const val 修飾靜態(tài)類或伴生對象的字段時時被稱為
常量
- 4: @JvmField修飾靜態(tài)類或伴生對象的字段時被稱為
常量
- 5: const val修飾的字段實現(xiàn)了內(nèi)聯(lián)(也就是copy代碼塊帶相應(yīng)位置)而@JvmField修飾的沒有
refrence:
https://www.kotlincn.net/docs/reference/properties.html
https://blog.egorand.me/where-do-i-put-my-constants-in-kotlin/