
Meta 釋出了一篇部落格表示,正在将其 Android 應用的 Java 代碼遷移到 Kotlin,并分享了這一過程中的一些經驗。
該公司認為,Kotlin 是一種流行的 Android 開發語言,與 Java 相比具有一些關鍵優勢。“是以,在我們努力使我們的開發工作流程更加高效的過程中,将 Meta 的 Android 開發轉向 Kotlin 是非常合理的......Kotlin 通常被認為是一種比 Java 更好的語言,在年度 Stack Overflow 開發者調查中,它的好感度要高于 Java。”
除了受歡迎程度外,Meta 還将最新的 Kotlin 版本與 Java 11(可用于 Android 開發的最新版本)進行了比較,并得出了 Kotlin 的一些主要優勢:可空性、函數式程式設計、更短的代碼、以及領域特定語言 (DSL) / 類型安全建構器等。
Facebook 軟體工程師 Omer Strulovich 指出,Meta 旗下幾個流行的 Android 應用 --Facebook、Instagram、Messenger、Portal 和 Quest 都已經開始從 Java 轉向 Kotlin。截至目前,Facebook、Messenger 和 Instagram 的 Android 應用程式都有超過 100 萬行 Kotlin 代碼,并且轉換率正在提高。Meta 的 Android 代碼庫總共已包含有超過 1000 萬行的 Kotlin 代碼。作為此次遷移的一部分,Meta 透露其也正在開源用于操作 Kotlin 代碼的各種示例和實用程式。
不過,采用 Kotlin 也有一些不能忽視的缺點。部落格内容指出,比如:兩種語言的混合代碼庫需要長時間的處理維護;以及 Kotlin 與 Java 相比,流行度還是存在明顯的差距,這意味着 Kotlin 可用的工具也更少。更糟糕的是所有 Kotlin 工具還都需要考慮 Kotlin 和 Java 的互操作性,這使得它們的實作就變得複雜。
最大的問題還在于建構時間。“我們從一開始就知道 Kotlin 的建構時間會比 Java 的要長。該語言及其生态系統更加複雜,Java 在優化其編譯器方面領先了 20 年。由于我們擁有多個大型應用程式,較長的建構時間可能會對我們的開發人員體驗産生負面影響。”
如何處理遷移
Meta 稱,遷移到 Kotlin 既簡單又非常複雜。因為 Kotlin 的設計允許從 Java 進行簡單的轉換,并具有經過深思熟慮的互操作性。這種設計使 JetBrains 能夠為開發人員社群提供 J2K,即 IntelliJ/Android Studio 中的 Java 到 Kotlin 轉換器。但 J2K 不是萬能的,遷移中的有些情況仍然很複雜。
遷移之前,該公司考慮了兩個選擇:
- 一個是可以使用 Kotlin 在 Meta 上編寫新代碼,但将大部分現有代碼保留在 Java 中。
- 還有一個是可以嘗試将幾乎所有内部代碼轉換為 Kotlin。
第一個選項的優勢很明顯,即少得多的工作量;但是這種方法也有兩個明顯的缺點。首先,在 Kotlin 和 Java 代碼之間實作互操作性引入了 Kotlin 中 platform types 的使用。platform types 會導緻運作時空指針取消引用,進而導緻崩潰,破壞了純 Kotlin 代碼提供的靜态安全優勢。在一些複雜的情況下,Kotlin 的空檢查省略還可能漏掉空值通過,進而引發空指針異常。例如,如果 Kotlin 代碼調用由 Java 接口實作的 Kotlin 接口,就會發生這種情況。其他問題包括 Java 無法将類型參數标記為可空性(直到最近才修複),以及 Kotlin 的重載規則考慮了可空性,而 Java 的重載規則卻沒有。
第二個缺點是考慮到 Meta 的大多數軟體開發都需要修改現有代碼。“如果我們的大部分代碼都是用 Java 編寫的,我們就無法讓我們的開發人員充分享受 Kotlin 的樂趣。由于遷移是一個漫長的過程,期望每個工程師在接觸檔案之前将檔案轉換為 Kotlin 既費力又低效。”
是以,Meta 方面最終選擇了第二條選項,決定将幾乎所有代碼轉換為 Kotlin。而在嘗試為現有應用程式引入 Kotlin 時,Meta 也遇到了很多麻煩,例如需要更新 Redex 以支援 Java 不生成的位元組碼模式。以及使用的某些内部庫依賴于在編譯期間進行位元組碼轉換來擷取更好的性能。而将其作為 Kotlin 編譯的一部分運作時,這部分代碼則無法生效。為此,Meta 專門建構了解決工具。
此外,他們還發現在現有工具中存在的一些差異。例如代碼審查或 wiki 中缺少 Kotlin 文法高亮顯示。“我們更新了我們正在使用的庫 Pygments,以使體驗與 Java 相媲美。我們更新了一些内部代碼修改工具,以便能夠處理 Kotlin。我們還建構了 Ktfmt,這是一個基于 google-java-format 的代碼和理念的确定性 Kotlin 格式化程式。”