Kotlin null的處理詳解

2022-10-07 09:09:08 字數 2114 閱讀 2219

kotlin null的處理詳解

nullpointerexception,俗稱npe,不管菜鳥還是老鳥們,都是不可避免,經常遇到的乙個異常,解釋起來很簡單,就「空指標」三個字。總是在一次不小心,而掉進這個陷阱裡。kotlin 的設計目標就是希望消除**中 null 引用帶來的危險, 也就是所謂的造成十億美元損失的大錯誤.

npe的原因

儘管kotlin希望消除**中的npe,我們總是不小心,總會不小心又掉進npe的陷阱,下面是可能npe的原因:

避免npe

在kotlin中,明確區分可以指向 null 的引用 (可為 null 引用) 與不可以指向null的引用 (非null引用). 比如, 乙個通常的 string 型別變數不可以指向 null:

var a: string = "abc"

a = null // 編譯錯誤

此時,你對a變數的任何呼叫都是安全的,因為它為非nul你可以對該引用做任何操作而不會報npe。就算對a賦值給null,編譯器都會報錯,不會讓你通過。

可是,實際開發時,不可能所有的變數不會null,總會有情況,變數是null的,此時該如何設定該變數呢?要允許null值的變數, 我們可以將變數宣告為可為null的字串, 寫作 string? :

var b: string? = "abc"

b = null // ok

這樣,我們是解決了變數可以設程式設計客棧置為null的問題,可npe的這個陷阱又設上了,如果再粗心大意,npe又來找麻煩了。

如果我們仍然需要訪問這個屬性, 對不對? 有以下幾種方法可以實現:

在條件語句中進行null檢查

通過條件語句,對變數檢查是否為null,對 null 和非 null 的兩種情況分別處理:

if (b != null && b.length > 0)

print("string of length $")

else

print("empty string")

注:該方案只是針對當前b的值,b的值在檢查以後,如果b的值被修改仍需對此值做非null檢查,也就是說每次修改b的值,都必須對b作非null驗證,這也導致了**的冗餘。

安全呼叫

什麼是安全呼叫?看起來有點不理解,既然是null怎麼還會有安全呢?

b?.length

在kotlin中,允許使用 「?.」操作符呼叫變數,其含義是如果b不是null,這個表示式將會返回b.length,否則返回 null.如果使用了」?.」,其表示式的值也應為 可為null的,比如int?,否則編譯器會報錯。

bob?.department?.head?.name

安全呼叫在鏈式呼叫的情況下非常有用.這樣的鏈式呼叫, 只要屬性鏈中任何乙個屬性為 null, 整個表示式就會返回 null.

?:操作符

如果 ?: 左側的表示式值不是null, 就會返回表示式的的值,否則, 返回右側表示式的值.

val l = b?.length ?: -1

如果b不為null,將返回b的長度,如果為null,將返回-1

注:只有在左側表示式值為 null 時, 才會計算右側表示式.

由於在 kotlin 中 throw 和 return 都是表示式, 因此它們也可以用在 elvis 操作符的右側. 這種用法可以帶來很大的方便, 比如, 可以用來檢查函式參vyrpll數值是否合法。

fun foo(node: node): string?

!! 操作符

對於b不為null的情況, 這個表示式將會返回這個非null值(比如, 在我們的例子中就是乙個 string 型別值), 如果b是 null, 這個表示式就

會丟擲乙個 npe:

val l = bwww.cppcns.com!!.length()

當b為null時就丟擲乙個異常,你可以捕獲它,而不是在不知道在某一角落裡呼叫時,才報出異常,抓頭撓腮半天,才找到npe在www.cppcns.com**。

安全的型別轉換

如果物件不是我們期望的目標型別, 那麼通常的型別轉換就會導致classcastexception,可以選擇使用安全的型別轉換, 如果轉換不成功, 它將會返回 null,這樣避免了轉換異常的丟擲。

val aint: int? = a as? int

本文標題: kotlin null的處理詳解

本文位址:

預處理詳解

預處理指令是以 號開頭的 行。號必須是該行除了任何空白字元外的第乙個字元。後是指令關鍵字,在關鍵字和 號之間允許存在任意個數的空白字元。整行語句構成了一條預處理指令,該指令將在編譯器進行編譯之前對源 做某些轉換。下面是部分預處理指令 指令 用途 空指令,無任何效果 include 包含乙個源 檔案 ...

事件處理詳解

之前做的多是手機端頁面,監聽事件也一直是 addeventlistener 現代瀏覽器基本都支援addeventlistener 除了萬惡的ie8及更低版本ie。雖說不用太管ie8了 個人愚見 但是還是有必要整理下之前相容性的處理方式 在html標籤中直接給屬性設定處理程式。html中加入了js 因...

異常處理詳解

作為乙個開發人員,你應該感受到通過try,catch,finally塊來構建乙個結構化異常處理機制的優點。net框架提供了一大堆異常處理層次來處理不同種類的異常。所有的異常都繼承自exception 基類 你可以通過繼承來實現自定義錯誤處理以擴充套件異常處理機制。不幸的是,很多開發人員都誤用了這種架...