【Kotlin】变量简介 ( 可空类型 | lateinit | 初始化判定 | 非空类型 | !! 与 ? 修饰符 | ?= ?. ?: 运算符 | 抽象属性变量)
文章目錄
- I . Kotlin 變量總結
- II . Kotlin 非空變量
- III . 非空變量不能賦空
- IV . lateinit 關鍵字
- V . lateinit 初始化判定
- VI . Kotlin 可空變量
- VII . !! 與 ? 修飾符
- VIII . ?= 與 ?. 與 ?: 運算符
- IX . 抽象屬性變量
I . Kotlin 變量總結
初學 Kotlin , 對變量機制不清楚的同學們 , 看完這篇博客基本就對變量的定義和使用有清晰的認識 ;
1 . 變量定義只有四種情況 : ① 非空變量 / 可空變量 直接賦值非空初始值 ; ② 可空變量使用 ?= null 賦空值 ; ③ 非空變量 ( 引用類型 ) 使用 lateinit 修飾 ; ④ 抽象屬性變量不初始化 ;
2 . !! 與 ? 修飾符 : 僅對于 可空類型 有效 , ? 高級不報錯 , !! 低級報空指針異常 ;
3 . ?= 與 ?. 與 ?: 運算符 : ?= 用于聲明可空類型 , ?. 用于空值校驗 . ?: 用于空值替換 ;
II . Kotlin 非空變量
1 . Kotlin 變量分類 : Kotlin 中的變量分為兩種 , 非空變量 和 可空變量 , 其中非空變量是困擾廣大 Java 開發(fā)者的一大難題 , 因為 Java 中沒有非空變量這個概念 , Kotlin 中各種 ?= , ?. , ?: , !! 等操作 , Java 中的所有變量都是可空的 ;
2 . Kotlin 變量的默認狀態(tài) : Kotlin 中變量默認是非空變量 , 默認狀態(tài)下 , Kotlin 必須進行初始化 ;
3 . 非空變量 初始化 和 延遲初始化 : 非空變量只能有下面兩種操作 , 抽象屬性變量情況特殊另作說明 ;
① 直接初始化 : 直接賦值一個非空初始值 , 非空變量不能賦值 null , 否則編譯器會報錯 ;
② 延遲初始化 : 引用類型變量使用 lateinit 關鍵字修飾 , 延遲初始化時機 , 可以在使用前進行初始化 ; 但是如果使用前沒有初始化 , 執(zhí)行時會報錯 ;
class Student(){// 延遲初始化lateinit var name : String// 直接初始化var age : Int = 0 }
4 . 特殊情況 : 如果是非空對象是抽象類中的抽象屬性 , 那么可以不進行初始化 , 但在其實現中 , 也是必須進行初始化或者延遲初始化的 ;
III . 非空變量不能賦空
1 . 非空變量 初始化時 不能賦值 null : 非空變量初始化時 , 不能為空 , 否則會報錯 Property must be initialized or be abstract ;
2 . 非空變量 使用時 不能賦值 null :
① 變量賦值 null 情況 : 如果為 Kotlin 的非空變量 , 也就是默認狀態(tài)下的變量 , 賦值 null , 編譯器直接報錯 ;
② 報錯信息如下 : Null can not be a value of a non-null type Int ;
③ 報錯分析 : 聲明的 var age : Int = 0 變量 , 其默認是 非空類型 , 即 age 變量 , 用戶調用時不能為空 , 故意賦值為空 , 系統(tǒng)不允許這種操作 ;
④ lateinit 不初始化情況 : 使用 lateinit 修飾的變量 , 但如果不初始化 , 那么調用肯定報錯 , 但是報的是未初始化錯誤 ; 不初始化不是為空 , 但不能調用 ;
IV . lateinit 關鍵字
lateinit 關鍵字 使用要求 : 只能修飾 非空類型 , 并且是 引用數據類型 ;
① 只能修飾非空變量 : 不能修飾可空變量 , 否則報錯信息如下 'lateinit' modifier is not allowed on properties of nullable types ;
② 只能修飾引用數據類型 : 不能修飾 888 種基本數據類型 , 否則報錯 'lateinit' modifier is not allowed on properties of primitive types ;
2 . 基礎數據類型非空變量 : 如果 非空變量 類型是 888 種基礎數據類型 , 那么該變量必須賦值一個數值 , 其不能被 lateinit 修飾 , 只能先隨意賦予一個初始值 , 一般設置 0 , False , 0F 等初始值 ;
V . lateinit 初始化判定
1 . 延遲初始化屬性初始化判定 : this::name.isInitialized
2 . 判定需求 : 非空變量 由于存在 延遲初始化 , 那么在調用該變量的時候 , 該變量有可能沒有進行初始化 , 需要判定該變量是否初始化 ;
3 . 本類中判定 : 延遲初始化 屬性 只能在本類中使用 this::屬性名稱.isInitialized 進行判定 , 如果返回 true , 說明已經初始化 , 如果返回 false , 說明該屬性還沒有進行初始化 ;
4 . 其它類中判定 : 如果要在其它類中判定本類某個屬性是否已經初始化 , 需要定義一個 public 方法 , 提供判定接口 , 如下代碼示例 :
5 . 代碼示例 :
class Student(){lateinit var name : Stringvar age : Int = 0fun isNameInitialized() : Boolean{println("this::name.isInitialized = ${this::name.isInitialized}")return this::name.isInitialized} }fun main() {var student = Student()if(student.isNameInitialized()) {println("name 屬性已經初始化完畢")}else{println("name 屬性沒有進行初始化")} }執(zhí)行結果 :
this::name.isInitialized = false name 屬性沒有進行初始化VI . Kotlin 可空變量
Kotlin 中的可空變量 , 與 Java 變量性質相同 , 所有的 Java 變量都是可空變量 ;
1 . 可空變量 聲明 : 聲明可空類型變量時 , 再其變量類型后 , 添加 ? 修飾 ; 注意不是變量名稱后 , 是變量類型后 ;
class Student(){var name : String ?= nullvar age : Int? = nullvar height : Int ?= 0 }2 . 可空變量初始化 :
① 必須初始化 : 可空變量也必須初始化 , 但可以初始化為 null 空值 ;
② 不能延遲初始化 : 可空類型不能使用 lateinit 關鍵字修飾 ;
VII . !! 與 ? 修飾符
1 . 可空類型前提 : !! 與 ? 修飾符 使用的前提是變量必須是 可空類型 , 非空類型不允許使用 !! 與 ? 修飾符 ;
2 . ? 和 !! 用法 : 放在變量后面 , 修飾變量 ; 如果變量不為空 , 沒有任何區(qū)別 , 下面討論變量為空的情況 ;
3 . ? 修飾變量 : 如果該變量為空 , 那么裝作什么都沒發(fā)生 , 繼續(xù)向后執(zhí)行 ; 下面的示例輸出結果是 Student : name = null , age = 0 ;
?. 運算符 : 這種用法 , 也可以看成是 ?. 運算符 , 意思就是如果不為空 , 才獲取值 , 如果為空 , 直接返回 null , 繼續(xù)向后執(zhí)行 ;
class Student(){var name : String ?= nullvar age : Int = 0 }fun main() {var student = Student()//輸出結果 : Student : name = null , age = 0println("Student : name = ${student.name?.length} , age = ${student.age}") }4 . !! 修飾變量 : 如果該變量為空 , 與 Java 一樣 , 報空指針異常 , 應用崩潰 ; 報空指針錯誤 kotlin.KotlinNullPointerException ;
class Student(){var name : String ?= nullvar age : Int = 0 }fun main() {var student = Student()//輸出結果 : Student : name = null , age = 0println("Student : name = ${student.name!!.length} , age = ${student.age}") }報錯信息 : 此時報錯空指針異常 ;
Exception in thread "main" kotlin.KotlinNullPointerExceptionat variable.VariableKt.main(Variable.kt:10)at variable.VariableKt.main(Variable.kt)VIII . ?= 與 ?. 與 ?: 運算符
1 . ?= 聲明可空類型 : ? 還有一個作用是聲明可空變量 , 此時 ? 修飾符必須在 變量類型之后 ; 聲明可空類型后 , 可以為其正常賦值 , 也可以為變量賦空值 ;
class Student(){var name : String? = "Tom"var age : Int ?= null }2 . ?. 運算符 : 這種用法 , 也可以看成是 ?. 運算符 , 意思就是如果不為空 , 才獲取值 , 如果為空 , 直接返回 null , 繼續(xù)向后執(zhí)行 ;
class Student(){var name : String ?= nullvar age : Int = 0 }fun main() {var student = Student()//Student : name = null , name length = null , age = 0println("Student : name = ${student.name} , name length = ${student.name?.length} , age = ${student.age}") }控制臺輸出 :
Student : name = null , name length = null , age = 03 . ? : 運算符 : 該運算符是雙目運算符 , 作用是前者如果為空 , 那么取后者的值 ;
① 與 Java 三木運算符 對比 : 在 Kotlin 中這個運算符與 Java 中不太一樣 , 這也是一個雙目運算符 , 中間不能有值 , Java 中該運算符是三木運算符 ;
class Student(){var name : String ?= nullvar age : Int = 0 }fun main() {var student = Student()//Student : name = Tom , name length = 888 , age = 0println("Student : name = ${student.name?:"Tom"} , name length = ${student.name?.length?:888} , age = ${student.age?:18}") }② 控制臺輸出 :
Student : name = Tom , name length = 888 , age = 0③ 代碼分析 :
student.name?:"Tom" 代碼中 , student.name 為空 , 那么取值后面的 "Tom" 字符串 , 因此打印的時候 , 打印 "Tom" 字符串 ;
student.name?.length?:888 代碼分析 :
student.name 是空的 , 取值 null ;
student.name?.length 相當于 null?.length 其取值也是 null ;
那么 student.name?.length?:888 相當于 null?:888 ;
最終取值是右側的 888 值 , 因此打印的時候打印 888 ;
IX . 抽象屬性變量
1 . Kotlin 變量初始化 : Kotlin 中的變量是必須進行初始化的 , 可空變量 與 非空變量要求不一樣 , 但是原則上都必須初始化 ;
① 非空變量 : 非空變量可以使用 lateinit 修飾 , 也可以直接進行非空值的初始化 , 直接賦值 null 報錯 ;
② 可空變量 : 必須初始化 , 哪怕初始化為 null 也可以 ; 不能使用 延遲初始化 ;
2 . 變量不用初始化的特殊情況 : 抽象類 的 抽象屬性 , 可以不進行初始化 , 但此時也不能使用 ; 該屬性實現的時候 , 重寫的屬性必須進行初始化操作 , 與普通變量要求一樣 ;
abstract class Variable(){//抽象類的抽象屬性可以不用初始化abstract var age : Int }//抽象類的實現類必須進行初始化 class Student() : Variable(){override var age: Int = 0 }總結
以上是生活随笔為你收集整理的【Kotlin】变量简介 ( 可空类型 | lateinit | 初始化判定 | 非空类型 | !! 与 ? 修饰符 | ?= ?. ?: 运算符 | 抽象属性变量)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【计算理论】确定性有穷自动机 ( 自动机
- 下一篇: 【Kotlin】Lambda 表达式 (