日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

編譯|燕珊,核子可樂

Meta 現在愛 Kotlin 多于 JAVA。

Facebook 母公司 Meta 正在將其 Android 應用的 Java 代碼遷移到 Kotlin。根據 Meta 的官方博客所述,截至今天,其 Android 代碼庫已經有超過 1000 萬行 Kotlin 代碼,旗下包括 Facebook、Instagram、Messenger、Portal 和 Quest 在內的應用都已經開始從 Java 轉向 Kotlin。

將代碼庫轉換為 Kotlin

Kotlin 是一種更年輕的編程語言,也依賴于 Java 虛擬機。Kotlin 由軟件工具制造商 JetBrains 創建,于 2011 年首次亮相,2016 年發布 1.0 版本。次年,它被 google 采用為 Android 開發的一級語言,并由其基金會管理,該基金會由 JetBrains 和 Google 資助。

到 2019 的 Google I/O 大會,Google 正式宣布,Kotlin 編程語言已成為 Android 應用開發人員的首選語言,并在當年年底表示前 1000 個 Android 應用程序中有近 60% 包含 Kotlin 代碼。

從 Google 自身來看,明面上它說自己選擇 Kotlin 的理由是它更簡潔、更安全、支持結構化并發,能更輕松地編寫異步代碼,并且可以與 Java 互操作。不過,另一個業界推測是可能跟那宗與 Oracle 曠日持久的 Java 侵權案有關—— Oracle 花了十多年的時間追究 Google 在 Android 中使用 Java API 的侵權索賠,最終 Oracle 敗訴。

回到 Meta,Facebook 軟件工程師 Omer Strulovich 對選擇 Kotlin 如此解釋道:“Kotlin 通常被認為是一種比 Java 更好的語言,在年度 Stack Overflow 開發人員調查中,其受歡迎程度高于 Java,”他還指出,由于近年來 Kotlin 已成為 Android 開發的流行語言,“因此,在努力使我們的開發工作流程更加高效的過程中,我們在 Meta 的安卓開發中轉向 Kotlin 是非常合理的……”

除了受歡迎之外,Meta 認為 Kotlin 擁有的主要優勢包括可空性、函數式編程、代碼更短、以及領域特定語言(DSL)等等。

不過,Strulovich 指出,過渡到 Kotlin 也有一些不可忽視的缺點,比如混合代碼庫可能難以維護,以及 Kotlin 雖然流行,但與 Java 相比還是有比較大的差距,工具集還不夠成熟。所有 Kotlin 工具都需要考慮 Kotlin 和 Java 的互操作性,這使得它們的實現變得復雜。

但 Meta 最大的擔憂還是構建時間。“我們從一開始就知道 Kotlin 的構建時間會比 Java 的要長。該語言及其生態系統更加復雜,Java 在優化其編譯器方面領先了 20 年。由于我們擁有多個大型應用程序,較長的構建時間可能會對我們的開發人員體驗產生負面影響。”

為什么不只用 Kotlin 來寫新代碼

Strulovich 沒有透露 Meta 何時開始這種轉變。Meta 本來可以選擇只用 Kotlin 編寫新代碼,但它最終還是決定將所有的 Android 應用程序都轉換過來。

根據 Strulovich 的說法,如果是只使用 Kotlin 來編寫新代碼,繼續保留大部分現有 Java 代碼的話,工作量明顯更低,但相應的也有兩個缺點:首先就是要在 Kotlin 和 Java 代碼之間實現互操作性,就需要引入 Kotlin 中的 platform 類型。Platform 類型會導致運行時中的空指針取消引用,進而引發崩潰,這就破壞了純 Kotlin 代碼提供的靜態安全優勢。在某些復雜情況下,Kotlin 的空檢查省略可能會漏掉空值,意外引發空指針異常。例如,如果 Kotlin 代碼調用由 Java 接口實現的 Kotlin 接口,就會發生這種情況。其他的問題還包括 Java 無法將類型參數標記為可空(最近才剛剛修復);Kotlin 的重載規則考慮到了可空性,Java 的重載規則卻沒有考慮到。

第二個缺點是,這種方式要求對 Meta 已經開發的大多數軟件進行代碼修改。如果繼續把大部分代碼保留為 Java 形式,那開發人員就沒法充分發揮 Kotlin 的優勢。

Kotlin 遷移大法

如今,Meta 旗下的 Android 版 Facebook、Messenger 和 Instagram 應用都擁有超過百萬行 Kotlin 代碼,而且轉換率也一路走高。縱觀整個 Android 代碼庫,其中的 Kotlin 代碼量已經超過千萬行。

起步階段

事實上,在嘗試為現有應用程序引入 Kotlin 時,Meta 遇到了不少麻煩。例如,團隊得更新 Redex 才能支持 Java 無法生成的字節碼模式。另外,其使用的某些內部庫要求在編譯期間進行字節碼轉換來獲取更好的性能。而在將這些庫納入 Kotlin 編譯過程時,這部分代碼無法正常起效。為此,Meta 針對這些問題構建了專門的解決工具。

Meta 還發現,現有工具之間存在不少沖突。例如,代碼審查和 wiki 工具無法對 Kotlin 語法進行高亮顯示。“我們還更新了之前使用的 Pygments 庫,確保其體驗與處理 Java 代碼時一致。我們更新了一些內部代碼修改工具,使其能夠支持 Kotlin。我們也構建了 Ktfmt,一款基于 google-java-format 編碼理念的確定性 Kotlin 格式化程序。”

遷移加速階段

在工具準備齊全之后,Meta 現在已經能將代碼中的任意部分轉換為 Kotlin。但每次遷移都需要大量樣板設計工作,只能由員工們手動完成。J2K 是一種通用工具,并不會去理解所轉換的代碼是在表達什么。因此,某些特定部分就只能進行手動調整。

最典型的例子就是 Junit 測試規則的使用。假設使用 ExpectedException 規則,來驗證是否拋出了正確的異常:

@Rule public ExpectedException expectedException = ExpectedException.none();

當 J2K 將這部分代碼轉換成 Kotlin 時,得到的就是:

@Rule var expectedException = ExpectedException.none()

這段代碼乍看之下與原先的 Java 代碼等價,但由于 Kotlin 使用了 site 注解,所以其實際上等價于:

@Rule private ExpectedException expectedException = ExpectedException.none();

public ExpectedException getExpectedException() {return expectedException

嘗試運行后,此測試會失敗并返回一個錯誤:“The @Rule expectedException must be public”,這是因為 Junit 發現了一條帶有 @Rule 注解的私有字段。這是個常見問題,論壇上面也已經有成熟答案:要么在字段中添加“@JvmField”;要么在注解中添加注解 use-site,也就是“@get:Rule”:

// 方案一:使用“get”作為注解的use-site@get:Rule var expectedException = ExpectedException.none()

// 方案二:只為沒有getter的Java字段生成JVM代碼@JvmField @Rule var expectedException = ExpectedException.none()

由于 J2K 無法(可能也不應該)感知 JUnit 的復雜性,所以沒能正確完成轉換。但即使 JUnit 不存在這個問題,J2K 在處理其他小眾框架的時候也肯定會掉類似的坑。

例如,很多 Android Java 代碼會使用 android.text.TextUtils 中的實用方法,例如 isEmpty,來簡化對某些字符串的檢查。但在 Kotlin 中,其實是有內置的標準庫方法 String.isNullOrEmpty 的。該方法之所以更好,是因為它能通過契約來告知 Kotlin 編譯器如果它返回 false,則被測試的對象不得再為 null,并將其智能轉換為 String。

Java 代碼也有不少類似的輔助方法,也有很多庫都實現了相同的基本方法。這一切都需要替換成標準的 Kotlin 方法,借此簡化代碼并保證編譯器能正確檢測出不可為空的類型。

Strulovich 表示,內部發現了許許多多類似的小小修復實例。有些難度不大(例如替換 isEmpty),有些則需要研究一番才能搞明白(例如 JUnit 規則)。還有一些其實屬于 J2K 出的錯,可能導致構建錯誤、運行時行為錯亂等問題。

為了解決這些問題,Meta 團隊將 J2K 轉換流程劃分成三個步驟:

首先,取一個 Java 包并準備將其轉換為 Kotlin。這個步驟主要解決錯誤,并完成相應的內部工具轉換。

第二步就是運行 J2K。團隊已經能夠以無頭模式運行 Android Studio 并調用 J2K,由此將整個管道作為腳本來運行。

最后一步,對新的 Kotlin 文件進行后處理。具體包括大部分自動重構與修復步驟,例如將 JUnit 規則標記為 @JvmField。在此步驟中,團隊還應用了自動更新 linter,并在無頭模式下應用各種 Android Studio 建議。

“當然,自動化并不足以解決所有問題,但至少能幫我們優先處理那些最常見的問題。”Strulovich 說。

在 Java 重構方面,Meta 使用的是 JavaASTParser 等工具,它能幫助解析某些類型。而在 Kotlin 這邊,團隊還沒有找到能夠解析類型的好辦法,所以選擇使用 Kotlin 編譯器 API。

Meta 還發布了一組自動重構方法(https://github.com/fbsamples/kotlin_ast_tools)。雖然不是很多,但希望能幫助更多開發者利用 Kotlin 編譯器解析器高效完成工作。

下一步

平均而言,Meta 發現遷移后的代碼行數減少了 11%。盡管網上各種案例引用的數字往往要比這高得多,但他們還是對這個數字感到滿意。

Strulovich 說,Meta 向 Kotlin 的遷移仍在進行中并在加速。“Kotlin 仍然缺乏一些我們在使用 Java 時已經習慣了的工具和優化,但我們正在努力縮小這些差距。隨著我們取得的進展和這些工具和庫的成熟,我們也將努力把它們反饋給社區。”

https://www.theregister.com/2022/10/25/meta_java_kotlin/

https://engineering.fb.com/2022/10/24/android/android-java-kotlin-migration/

分享到:
標簽:Kotlin
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定