kotlin只允許在變量前面聲明兩種關鍵字:val或者var
val:(value的簡寫)用來聲明一種值,這種值在賦值之後不可改變,對應Java中的final(這不是常量嗎…)
var:(variable的簡寫),聲明變量
類型推導機制
既然在變量前只允許聲明兩種關鍵字,那麼他怎麼知道這是什麼類型呢?
比如我們在剛剛的代碼上加入一行:var a = 10
package com.example.test
fun main() {
var a = 1
print("hello world! a is:" + a)
}
這樣寫運行是沒什麼問題的,但是會報一個警告:Convert concatenation to template
也就是說他不推薦我們用+去拼接字符串,按照提示自動幫我們改成
package com.example.test
fun main() {
var a = 1
print("hello world! a is:$a")
}
運行結果是一樣的:hello world! a is:1
我們定義了一個變量並將一個數字賦值給他,那麼這個變量的類型就是整型變量,如果將字符串賦值給他那麼他就是個字符串變量,不可能是其他,這就是推導機制。
但是,當我對一個變量延遲賦值怎麼辦?他是一個什麼類型的值呢?
這時候,Kotlin的類型推倒機制就不能正常工作了,這時候就需要顯示的去聲明變量,Kotlin提供了對這一功能的支持
語法:val a: Int = 1
這時,我們顯示的聲明瞭a爲Int型,如果再去賦值爲String型,就會報錯
這裏需要注意的地方:Int首字母是大寫的,拋棄了Java中的基本數據類型
這一個小小的差別意味着,在Java中這是一個基本數據類型,而在Kotlin中,他變成了一個類,他具有屬性和方法
而Java由於基本數據類型的存在,也使得他不是一個完完全全的面嚮對象語言,只能算是半面嚮對象語言
Java和Kotlin數據類型對照表
Java基本數據類型 | Kotlin對象數據類型 | 數據類型說明 |
---|---|---|
byte | Byte | 字節型 |
int | Int | 整型 |
short | Short | 短整型 |
long | Long | 長整型 |
float | Float | 單精度浮點型 |
double | Double | 雙精度浮點型 |
char | Char | 字符型 |
boolean | Boolean | 布爾型 |
爲什麼設計val,只使用var不行嗎?
其實這是爲了解決Java中final關鍵字沒有被合理使用的問題
在Java中,如果不手動聲明final,那麼這個變量就是可變的,這不一定是個好事,你永遠不知道這個值被誰在什麼時候給修改了,從而帶來bug的難以查找和定位,除非一個值可以變,否則都應該加上final,但是很多人沒這個意識,僅僅是因爲Java對此不是強制的
不僅僅是這些,final修飾的關鍵字與不做修飾的相比,性能上也會有些差異:
final修飾的全局變量會被當做常量來使用,放入Constant pool中。
被final修飾的局部變量會直接被優化成常量,字節碼直接存儲運算後的常量。
由於Java規範規定,final修飾的方法不能被重寫,所以jvm實現中invokevirtual在調用final修飾的方法(final方法是非虛方法)時會省去對方法接收者的多態選擇
作者:Joash
鏈接:https://www.zhihu.com/question/38264283/answer/82342134
來源:知乎
所以,在kotlin中,我們儘量使用val去修飾變量,只有當val不滿足時,才聲明爲var
推薦閱讀
歡迎關注這個不是技術號的公衆號,我們聊聊別的。