Android 開發者自述:為什麼我要改用 Kotlin?
本文原載於 droidyue.com(技術小黑屋),原標題為《為什麼我要改用 Kotlin》。本文作者為Flipboard 中國 Android 研發工程師段建華。極客公園已經獲得轉載授權。
寫在前面的話,作為一個不熬夜的人,一覺醒來發現 Kotlin 成為了 Android 的官方語言,可謂是大喜過望。為了趁熱打鐵,我決定提前三天放出原定本周日 Release 的文章。希望能及時讓大家了解一下 Kotlin。
相信很多開發人員,尤其是 Android 開發者都會或多或少聽說過 Kotlin,當然如果沒有聽過或者不熟悉也沒有關係。因為本篇文章以及博客後期的內容會涉及到很多關於 Kotlin 的知識分享。
在寫這篇文章前的一個多月,Flipboard 中國的 Android 項目確定了正式將 Kotlin 作為項目開發語言,這就意味著新增的代碼文件將以 Kotlin 代碼格式出現,而且同時舊的 Java 代碼也將會陸陸續續翻譯成 Kotlin 代碼。在使用 Kotlin 的這段時間,被它的簡潔,高效,快捷等等特點震撼,所以有必要寫一篇文章來談一談 Kotlin 的特性,如若能取得推廣 Kotlin 的效果則倍感欣慰。
Kotlin的「簡歷」
- 來自於著名的 IDE IntelliJ IDEA(Android Studio 基於此開發) 軟體開發公司 JetBrains(位於東歐捷克)
- 起源來自 JetBrains 的聖彼得堡團隊,名稱取自聖彼得堡附近的一個小島 (Kotlin Island)
- 一種基於 JVM 的靜態類型編程語言
來自知名的工具開發商 JetBrains,也就決定了 Kotlin 的基因中必然包含實用與高效等特徵。那我們接下來看一看 Kotlin 的特點,當然這也是我改用 Kotlin 的重要原因。
語法簡單,不啰嗦
- Kotlin 支持類型推斷,沒有 Java 那樣的啰嗦。
- 另外用 var 表示變數,val 表示常量更加的簡潔
- 方法也很簡單,連 function 都縮寫成了 fun,平添了幾分雙關之意。
- 類的繼承和實現很簡單,使用:即可
- Kotlin 每個句子都不需要加分號 (;)
空指針安全
空指針(NullPointerException 或 NPE)是我們使用 Java 開發程序中最常見的崩潰了。因為在 Java 中我們不得不寫很多防禦性的代碼,比如這樣:
在 Kotlin 中空指針異常得到了很好的解決。
- 在類型上的處理,即在類型後面加上?,即表示這個變數或參數以及返回值可以為 null,否則不允許為變數參數賦值為 null 或者返回 null
- 對於一個可能是 null 的變數或者參數,在調用對象方法或者屬性之前,需要加上?,否則編譯無法通過。
如下面的代碼就是 Kotlin 實現空指針安全的一個例子,而且相對 Java 實現而言,簡直是一行代碼搞定的。
關於空指針安全的原理,可以參考這篇文章研究學習Kotlin的一些方法。支持方法擴展
很多時候,Framework 提供給我們的 API 往往都時比較原子的,調用時需要我們進行組合處理,因為就會產生了一些 Util 類,一個簡單的例子,我們想要更快捷的展示 Toast 信息,在 Java 中我們可以這樣做。
但是 Kotlin 的實現卻讓人驚奇,我們只需要重寫擴展方法就可以了,比如這個 longToast 方法擴展到所有的 Context 對象中,如果不去追根溯源,可能無法區分是 Framework 提供的還是自行擴展的。
注意:Kotlin 的方法擴展並不是真正修改了對應的類文件,而是在編譯器和 IDE 方面做得處理。使我們看起來像是擴展了方法。Lambda, 高階函數,Streams API, 函數式編程支持
所謂的 Lambda 表達式是匿名函數,這使得我們的代碼會更加的簡單。比如下面的代碼就是 lambda 的應用。
所謂的高階函數就是:- 可以接受函數作為參數
- 也可以返回函數作為結果
舉一個接受函數作為參數的例子。在 Android 開發中,我們經常使用 SharedPreference 來存儲數據,如果忘記調用 apply 或者 commit 則數據修改不能應用。利用 Kotlin 中的高階函數的功能,我們能更好的解決這個問題:
當然這上面的例子中我們也同時使用了方法擴展這個特性。
Kotlin 支持了 Streams API 和方法引用,這樣函數式編程更加方便。比如下面的代碼就是我們結合 Jsoup,來抓取某個 proxy 網站的數據,代碼更加簡單,實現起來也快速。
字元串模板
無論是 Java 還是 Android 開發,我們都會用到字元串拼接,比如進行日誌輸出等等。在 Kotlin 中,字元串模板是支持的,我們可以很輕鬆的完成一個字元串數組的組成:
注意:關於字元串拼接可以參考這篇文章Java細節:字元串的拼接。與 Java 交互性好
Kotlin 和 Java 都屬於基於 JVM 的編程語言。Kotlin 和 Java 的交互性很好,可以說是無縫連接。這表現在:
- Kotlin 可以自由的引用 Java 的代碼,反之亦然。
- Kotlin 可以現有的全部的 Java 框架和庫
- Java 文件可以很輕鬆的藉助 IntelliJ 的插件轉成 kotlin
Kotlin 應用廣泛
Kotlin 對 Android 應用開發支持廣泛,諸多工具,比如 kotterknife(ButterKnife Kotlin 版),RxKotlin,Anko 等等,當然還有已經存在的很多 Java 的庫都是可以使用的。
除此之外,Kotlin 也可以編譯成 Javascript。最近使用 Kotlin 寫了一段抓取 proxy 的代碼,實現起來非常快捷。甚至比純 JavaScript 實現起來要快很多。
關於性能
Kotlin 的執行效率和 Java 代碼的執行效率理論上一致的。有時候 Kotlin 可能會顯得高一些,比如 Kotlin 提供了方法的 inline 設置,可以設置某些高頻方法進行 inline 操作,減少了運行時的進棧出棧和保存狀態的開銷。
讀到這裡,是不是想要嘗試一下 Kotlin 呢,它簡潔的語法,彙集諸多特性,高效率實現等等,已經在國外風生水起,國外的 Pintereset, Square, Flipboard 等公司已經開始應用到生產中。
關於轉向 Kotlin
其實,我在做決定之前(當時 Kotlin 還沒有被欽定)也曾有過考慮,是不是選擇了 Kotlin 就意味著放棄 Java 呢,冷靜下來想一想,其實並不是那麼回事,因為 Kotlin 與 Java 語法太相近,以及在 Kotlin 中無時無刻不在和 Java 相關的東西打交道,所以這點顧慮不是問題的。
對於個人的項目來轉向 Kotlin,通常不是很難的選擇,畢竟 Kotlin 是那麼優秀的語言,相信很多人還是願意嘗試並使用這個事半功倍的語言的。
而比較難抉擇的情況是如果如何讓團隊轉用 Kotlin,個人認為團隊難以轉用的原因有很多,比如學習成本,歷史包袱等等。但其實根本原因還是思維方式的問題,歪果仁喜歡用工具來提升開發效率,因為人力成本很高。而國內團隊提高效率的辦法通常是增加成員。好在 Flipboard 美國團隊自 2015 年(可能更早)就引入了 Kotlin,因此中國團隊這邊選用 Kotlin 也更加順水推舟。當然更主要的是目前團隊規模不大,成員一致認可 Kotlin 的優點。
關於團隊轉用 Kotlin 的方法,一般比較行得通的辦法是自上而下的推行。這就意味著要麼直接的技術負責人比較開明要麼就是需要有人來不斷推介來影響團隊。
做個比較現實的比擬,Java 就像是一趟從我的家鄉保定開往北京西的耗時將近 2 個小時甚至更長的普通列車,而 Kotlin 則是那趟僅需 40 分鐘就能到達的高鐵。通常的人都會選擇高鐵,因為它節省了時間和提高了體驗。這個時間和體驗對應編程中的,我想應該是高效率和高可讀性,可維護性的代碼。
現在好了,有了 Google 的支持,Kotlin 轉 Android 相信在不久的將來就會全面展開。篡改 Python 的一句名言「人生苦短,我用 Kotlin」,這樣一個高效實用的語言應該會被越來越多的團隊所接受,並應用到開發生產中。當然也希望在國內環境下大放異彩。
推薦閱讀:
※Kotlin 互動式命令行工具:kotlinc
※#Kotlin# 一年の使用報告 - 函數式思想
※Kotlin 讓使用 Android API 變得輕鬆
※編程雜談(一) - 英文是很重要的