本篇內容主要講解“Kotlin內聯類與類型別名的使用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Kotlin內聯類與類型別名的使用方法”吧!
內聯類的支持版本目前是1.3及以上。
內聯類的使用其實很簡單,只需要我們在class前面加上一個inline關鍵字即可,如下面這樣:
inline class WoMan(private val name: String) {val length: Intget() =name.length fun greet() {println("Hello, $name") } }
跟普通的類看上去沒什么區別,不過我們show bytecode之后看看代碼是怎么樣的
public static final int getLength_impl/* $FF was: getLength-impl*/(String $this) { return $this.length();}
public static final void greet_impl/* $FF was: greet-impl*/(String $this) { String var1 = "Hello, " + $this; boolean var2 = false; System.out.println(var1);}
String name = WoMan.constructor-impl("唐三");WoMan.greet-impl(name);
其實最后都變成了靜態方法調用了,那如果我們不用inline關鍵字修飾的話會是怎么樣呢
public final class WoMan { private final String name; public final int getLength() { return this.name.length(); } public final void greet() { String var1 = "Hello, " + this.name; boolean var2 = false; System.out.println(var1); } public WoMan(@NotNull String name) { Intrinsics.checkNotNullParameter(name, "name"); super(); this.name = name; } }
其實就是簡單的Java類而已,調用的話我們還是得對象方法才可以。
WoMan name = new WoMan("唐三");name.greet();
然后我們再說一下內聯函數的使用要求:內聯類必須含有唯?的?個屬性在主構造函數中初始化。在運?時,將使?這個唯?屬性來表?內聯類的實例。
其實就是起到了包裝器的作用,我們發現使用的時候跟普通的類的使用方法一樣,沒有任何區別,但是我們在性能上就已經做得很好了,我們在實例化一個對象的時候,就會把對象存儲到JVM堆上,我們在存儲和使用對象實例時會有性能損失 - 堆分配和內存提取的性能代價很高。雖然看起來每個對象性能開銷微不足道,但是累積起來,它對代碼運行速度產生嚴重的影響。如果我們能夠在不受性能影響的情況下獲得強類型系統的所有好處,那不是很好嗎?實際上,Kotlin新特性inline class
就是為了解決這樣的問題而設計的。
這樣我們即在性能方面做了節省,還不影響我們獲得強類型的使用的所有的好處,這樣何樂不為呢?
上面的例子當中我們聲明的內聯類對象的時候其實就相當于聲明了我們內聯類里面包裝的變量而已,從而避免了對象的創建和銷毀。
內聯類的柱構造函數里面只能有一個參數并且是只能是可讀的,但是呢,它的內部是可以擁有成員屬性的,只要它們僅基于構造器中那個基礎值計算,或者從可以靜態解析的某個值或對象計算 - 來自單例,頂級對象,常量等??梢詫翟O置為私有的,但是構造函數必須是共有的,我們的內聯類可以繼承接口,但是不能繼承類,也不能被任何類繼承,不能作為內部類實現,也不支持內聯枚舉類。
typealias類型別名的時候跟內聯類有一些相似之處,也容易混淆。
因為它們都包含基礎類型,所以內聯類很容易與類型別名混淆。但是有一些關鍵的差異使它們在不同的場景下得以應用。
比如我們需要定義一個變量,可能是用戶名稱或者用戶密碼等,那么類型肯定是字符串嘛,作為函數形參的聲明的時候我們一般都是name:String即可,可是我們想表達的更清楚一些呢,就可以用類型別名還使用我們自己定義的名字。
typealias userName = String
class WoMan(private val name: userName) {}
可以看到使用起來跟String沒什么區別,只是表達的更清楚了。
內聯函數一方面來說使用的時候我們需要進行拆箱的操作,而類型別名就不需要了,可是類型別名在同一類型的時候是無法區分,比如我們同事聲明了兩個類型別名username,password而且都是字符串,可是我們的定義函數方法里面需要的參數是可以改變順序的,因為我們的參數類型雖然是不同的類型別名,但是都是一個String類型的,所以這一點內聯函數是完全可以不用考慮的,因為內聯函數就是一個基本類型的包裝體,不同的包裝體肯定不一樣,所以我們的順序是不能改變的。
typealias userName = Stringtypealias passWord = Stringfun test(name: userName, pwd: passWord) { }
上面就很容易看到了,當我們name和pwd的傳參數順序不一樣的時候,編譯器是無法做出檢測的,運行期也不會報錯的。
但是內聯函數就是包裝之后就是不同的類。
inline class Username(val name: String)inline class Password(val pwd: String)fun test2(name: Username, pwd: Password) { }
當我們調用函數的時候傳遞的參數順序改變的話,編譯器是會報錯的。
所以使用起來各取所需吧,各有各的使用場景。
到此,相信大家對“Kotlin內聯類與類型別名的使用方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。