引入可空性,將運行時錯誤轉化編譯時錯誤。java
該操做符組合空處理和方法調用。若是是null跳過該方法調用,返回null值。安全
若是第一個值不爲空返回該值,不然返回第二個值ide
若是不匹配就返回null函數
foo!!
,若是foo爲空就拋出NPEthis
let函數使咱們更加處理傳遞給函數的空參數,確保它是非空參數。spa
fun sendEmailTo(email: String) { println("Sending email to $email") } >>> val email: String? = ... >>> sendEmailTo(email) ERROR: Type mismatch: inferred type is String? but String was expected
若是傳遞一個空參數會錯誤,若是咱們使用let函數就能輕鬆的處理。code
email?.let { email -> sendEmailTo(email) } //更加簡單的寫法 email?.let { sendEmailTo(it) }
若是email不爲空才傳遞到要求非空參數的函數。ci
kotlin的類須要初始化全部的屬性,若是咱們不能提供初始化值,將其設置爲可空值,初始化爲null時,每次改屬性都須要使用?.或!!操做符。hash
爲了解決這一問題,kotlin提供了lateinit關鍵詞來延遲初始化屬性,若是咱們訪問該屬性卻沒有初始化時會報異常 "lateinit property myService has not been initialized"it
kotlin中的this能夠爲null值,因此有許多空類型的擴展函數使用它處理null的狀況。
例如kotlin中String?的擴展方法:
/** * Returns `true` if this nullable char sequence is either `null` or empty or consists solely of whitespace characters. */ @kotlin.internal.InlineOnly public inline fun CharSequence?.isNullOrBlank(): Boolean = this == null || this.isBlank()
默認,全部的類和函數參數的都是可空。一個類型參數能夠取代任意類型,包括空類型,這種狀況,聲明使用類型參數做爲可空類型,例如咱們生存參數類型T沒有在後面標記問好。
fun <T> printHashCode(t: T) { println(t?.hashCode()) } >>> printHashCode(null) null
上面T表明Any?,因此它的值能夠爲Null,明確使T爲非空時,必需要使用<T: Any>
多數狀況下,變量、屬性、參數、和返回類型,kotlin的Int類型編譯成java的int原始類型。
原始類型Int做爲泛型函數參數時會編譯成對應的java包裹類型。
例如:Int做爲集合類型參數,集合將會保存java.lang.Integer類型,對應的包裹類型。
Kotlin的Unit類型在函數中的使用等於java的void。表示沒有返回值。
主要區別是Unit能夠做爲類型參數。Unit類型只有一個值存在,也成爲Unit在函數中隱式返回。在重載一個函數返回泛型參數時能夠使函數返回Unit類型。
interface Processor<T> { fun process(): T } class NoResultProcessor : Processor<Unit> { override fun process() { //不須要明確返回Unit類型 // do stuff } }
fun fail(message: String): Nothing { throw IllegalStateException(message) }
注意:函數返回Nothing能夠做爲Elvis操做符右邊處理條件確認:
val address = company.address ?: fail("No address") println(address.city)