1. 程式人生 > >Kotlin開發二 kotlin型別的可空性

Kotlin開發二 kotlin型別的可空性

1 可空型別

kotlin中引入了Type?來表示Type型別是可能為null,這樣從編譯上避免了很多NPE的發生。

Type? = Type or null

問號?可以載入任何型別後面,表示這個型別的變數可能為null
沒有問號?表示這種型別的變數不為null。
對可空型別的操作,kotlin中考慮了NPE的情況,做了一些限制

    //可空型別
    var name:String? = null
    //非空型別
    var personName:String = "娃哈哈"

對可空型別的變數呼叫它的方法必須做null判斷,如果左了判斷編譯器會記住判斷結果

    var length:Int = if (name != null) name.length else 0

可空型別變數不能直接賦值給非空型別變數

    // error
personName = name;

可空型別的值不能傳遞給非空型別引數

fun getLength(s:String):Int = s.length
//error
getLength(name)

但是可以把非空型別賦值給可空型別變數

    //ok
    name = personName;

完整例項如下:

fun main(args: Array<String>) {
    //可空型別
var name:String? = null //非空型別 var personName:String = "娃哈哈" var length:Int = if (name != null) name.length else 0 //error getLength(name) //ok //name = personName; // error personName = name; } fun getLength(s:String):Int = s.length

2 安全呼叫運算子”?.”

安全呼叫運算子允許把一次null檢查和一次方法或者屬性呼叫合併成一個操作。

Xxx?.xxx = if(Xxx != null) Xxx.xxx else null

注意呼叫結果是可空型別的
我們來改寫前面的例子

    var len:Int? = name?.length

對於方法的呼叫也類似,就不舉例子了。

3 Elvis運算子 “?:”

與”?.”運算子類似,”?:”接受兩個運算數,如果第一個不為null,表示式就是第一個值,否則取第二個值

Xxx?:xxx = if(Xxx != null) Xxx else xxx

注意”?:”經常與”?.”運算子一起呼叫,因為我們經常有這樣一種呼叫:
如果Xxx不為null,就呼叫Xxx.A,否則返回一個預設值
例項如下:

    var length2:Int = name?.length?:0

單獨使用”?:”一般用於可空型別賦值給非空型別

    //可空型別
    var name:String? = null
    //非空型別
    var personName:String = "娃哈哈"
    personName = name?:""

4 安全轉換符”as?”

as用來進行型別轉換,在java中如果型別不匹配將會拋異常,在kotlin中為了減少這種異常丟擲,如果認為型別不匹配使用as?可以直接返回null。從而減少異常發生

xxx as? Type = if(xxx is Type) xxx as Type else null

as?與?:一起使用,見下面的例子

class People(val name:String,val age:Int){

    override fun equals(other: Any?): Boolean {
        var another = other as? People?:return false

        return another.name == name && another.age == age
    }

    override fun hashCode(): Int {
        return age.hashCode()*31 + name.hashCode()
    }
}

5 非空斷言”!!”

非空斷言主要用作將任何型別轉換為非空型別,如果被轉換的值是null,將會丟擲NPE異常。

xxx!! = if(xxx != null) xxx else throw NPE

例項如下:

fun ignoreNulls(s:String?){
    var str = s!!
    println(str.length)
}

如果s為null,將會在var str = s!!丟擲NPE異常

關於可空型別還有let函式,擴充套件等,後續再逐步介紹,或者參考相關文件