亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

編譯|燕珊,核子可樂(lè)

Meta 現(xiàn)在愛(ài) Kotlin 多于 JAVA。

Facebook 母公司 Meta 正在將其 Android 應(yīng)用的 Java 代碼遷移到 Kotlin。根據(jù) Meta 的官方博客所述,截至今天,其 Android 代碼庫(kù)已經(jīng)有超過(guò) 1000 萬(wàn)行 Kotlin 代碼,旗下包括 Facebook、Instagram、Messenger、Portal 和 Quest 在內(nèi)的應(yīng)用都已經(jīng)開(kāi)始從 Java 轉(zhuǎn)向 Kotlin。

將代碼庫(kù)轉(zhuǎn)換為 Kotlin

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

到 2019 的 Google I/O 大會(huì),Google 正式宣布,Kotlin 編程語(yǔ)言已成為 Android 應(yīng)用開(kāi)發(fā)人員的首選語(yǔ)言,并在當(dāng)年年底表示前 1000 個(gè) Android 應(yīng)用程序中有近 60% 包含 Kotlin 代碼。

從 Google 自身來(lái)看,明面上它說(shuō)自己選擇 Kotlin 的理由是它更簡(jiǎn)潔、更安全、支持結(jié)構(gòu)化并發(fā),能更輕松地編寫(xiě)異步代碼,并且可以與 Java 互操作。不過(guò),另一個(gè)業(yè)界推測(cè)是可能跟那宗與 Oracle 曠日持久的 Java 侵權(quán)案有關(guān)—— Oracle 花了十多年的時(shí)間追究 Google 在 Android 中使用 Java API 的侵權(quán)索賠,最終 Oracle 敗訴。

回到 Meta,F(xiàn)acebook 軟件工程師 Omer Strulovich 對(duì)選擇 Kotlin 如此解釋道:“Kotlin 通常被認(rèn)為是一種比 Java 更好的語(yǔ)言,在年度 Stack Overflow 開(kāi)發(fā)人員調(diào)查中,其受歡迎程度高于 Java,”他還指出,由于近年來(lái) Kotlin 已成為 Android 開(kāi)發(fā)的流行語(yǔ)言,“因此,在努力使我們的開(kāi)發(fā)工作流程更加高效的過(guò)程中,我們?cè)?Meta 的安卓開(kāi)發(fā)中轉(zhuǎn)向 Kotlin 是非常合理的……”

除了受歡迎之外,Meta 認(rèn)為 Kotlin 擁有的主要優(yōu)勢(shì)包括可空性、函數(shù)式編程、代碼更短、以及領(lǐng)域特定語(yǔ)言(DSL)等等。

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

但 Meta 最大的擔(dān)憂還是構(gòu)建時(shí)間。“我們從一開(kāi)始就知道 Kotlin 的構(gòu)建時(shí)間會(huì)比 Java 的要長(zhǎng)。該語(yǔ)言及其生態(tài)系統(tǒng)更加復(fù)雜,Java 在優(yōu)化其編譯器方面領(lǐng)先了 20 年。由于我們擁有多個(gè)大型應(yīng)用程序,較長(zhǎng)的構(gòu)建時(shí)間可能會(huì)對(duì)我們的開(kāi)發(fā)人員體驗(yàn)產(chǎn)生負(fù)面影響。”

為什么不只用 Kotlin 來(lái)寫(xiě)新代碼

Strulovich 沒(méi)有透露 Meta 何時(shí)開(kāi)始這種轉(zhuǎn)變。Meta 本來(lái)可以選擇只用 Kotlin 編寫(xiě)新代碼,但它最終還是決定將所有的 Android 應(yīng)用程序都轉(zhuǎn)換過(guò)來(lái)。

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

第二個(gè)缺點(diǎn)是,這種方式要求對(duì) Meta 已經(jīng)開(kāi)發(fā)的大多數(shù)軟件進(jìn)行代碼修改。如果繼續(xù)把大部分代碼保留為 Java 形式,那開(kāi)發(fā)人員就沒(méi)法充分發(fā)揮 Kotlin 的優(yōu)勢(shì)。

Kotlin 遷移大法

如今,Meta 旗下的 Android 版 Facebook、Messenger 和 Instagram 應(yīng)用都擁有超過(guò)百萬(wàn)行 Kotlin 代碼,而且轉(zhuǎn)換率也一路走高??v觀整個(gè) Android 代碼庫(kù),其中的 Kotlin 代碼量已經(jīng)超過(guò)千萬(wàn)行。

起步階段

事實(shí)上,在嘗試為現(xiàn)有應(yīng)用程序引入 Kotlin 時(shí),Meta 遇到了不少麻煩。例如,團(tuán)隊(duì)得更新 Redex 才能支持 Java 無(wú)法生成的字節(jié)碼模式。另外,其使用的某些內(nèi)部庫(kù)要求在編譯期間進(jìn)行字節(jié)碼轉(zhuǎn)換來(lái)獲取更好的性能。而在將這些庫(kù)納入 Kotlin 編譯過(guò)程時(shí),這部分代碼無(wú)法正常起效。為此,Meta 針對(duì)這些問(wèn)題構(gòu)建了專門(mén)的解決工具。

Meta 還發(fā)現(xiàn),現(xiàn)有工具之間存在不少?zèng)_突。例如,代碼審查和 wiki 工具無(wú)法對(duì) Kotlin 語(yǔ)法進(jìn)行高亮顯示。“我們還更新了之前使用的 Pygments 庫(kù),確保其體驗(yàn)與處理 Java 代碼時(shí)一致。我們更新了一些內(nèi)部代碼修改工具,使其能夠支持 Kotlin。我們也構(gòu)建了 Ktfmt,一款基于 google-java-format 編碼理念的確定性 Kotlin 格式化程序。”

遷移加速階段

在工具準(zhǔn)備齊全之后,Meta 現(xiàn)在已經(jīng)能將代碼中的任意部分轉(zhuǎn)換為 Kotlin。但每次遷移都需要大量樣板設(shè)計(jì)工作,只能由員工們手動(dòng)完成。J2K 是一種通用工具,并不會(huì)去理解所轉(zhuǎn)換的代碼是在表達(dá)什么。因此,某些特定部分就只能進(jìn)行手動(dòng)調(diào)整。

最典型的例子就是 Junit 測(cè)試規(guī)則的使用。假設(shè)使用 ExpectedException 規(guī)則,來(lái)驗(yàn)證是否拋出了正確的異常:

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

當(dāng) J2K 將這部分代碼轉(zhuǎn)換成 Kotlin 時(shí),得到的就是:

@Rule var expectedException = ExpectedException.none()

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

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

public ExpectedException getExpectedException() {return expectedException

嘗試運(yùn)行后,此測(cè)試會(huì)失敗并返回一個(gè)錯(cuò)誤:“The @Rule expectedException must be public”,這是因?yàn)?Junit 發(fā)現(xiàn)了一條帶有 @Rule 注解的私有字段。這是個(gè)常見(jiàn)問(wèn)題,論壇上面也已經(jīng)有成熟答案:要么在字段中添加“@JvmField”;要么在注解中添加注解 use-site,也就是“@get:Rule”:

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

// 方案二:只為沒(méi)有g(shù)etter的Java字段生成JVM代碼@JvmField @Rule var expectedException = ExpectedException.none()

由于 J2K 無(wú)法(可能也不應(yīng)該)感知 JUnit 的復(fù)雜性,所以沒(méi)能正確完成轉(zhuǎn)換。但即使 JUnit 不存在這個(gè)問(wèn)題,J2K 在處理其他小眾框架的時(shí)候也肯定會(huì)掉類似的坑。

例如,很多 Android Java 代碼會(huì)使用 android.text.TextUtils 中的實(shí)用方法,例如 isEmpty,來(lái)簡(jiǎn)化對(duì)某些字符串的檢查。但在 Kotlin 中,其實(shí)是有內(nèi)置的標(biāo)準(zhǔn)庫(kù)方法 String.isNullOrEmpty 的。該方法之所以更好,是因?yàn)樗芡ㄟ^(guò)契約來(lái)告知 Kotlin 編譯器如果它返回 false,則被測(cè)試的對(duì)象不得再為 null,并將其智能轉(zhuǎn)換為 String。

Java 代碼也有不少類似的輔助方法,也有很多庫(kù)都實(shí)現(xiàn)了相同的基本方法。這一切都需要替換成標(biāo)準(zhǔn)的 Kotlin 方法,借此簡(jiǎn)化代碼并保證編譯器能正確檢測(cè)出不可為空的類型。

Strulovich 表示,內(nèi)部發(fā)現(xiàn)了許許多多類似的小小修復(fù)實(shí)例。有些難度不大(例如替換 isEmpty),有些則需要研究一番才能搞明白(例如 JUnit 規(guī)則)。還有一些其實(shí)屬于 J2K 出的錯(cuò),可能導(dǎo)致構(gòu)建錯(cuò)誤、運(yùn)行時(shí)行為錯(cuò)亂等問(wèn)題。

為了解決這些問(wèn)題,Meta 團(tuán)隊(duì)將 J2K 轉(zhuǎn)換流程劃分成三個(gè)步驟:

首先,取一個(gè) Java 包并準(zhǔn)備將其轉(zhuǎn)換為 Kotlin。這個(gè)步驟主要解決錯(cuò)誤,并完成相應(yīng)的內(nèi)部工具轉(zhuǎn)換。

第二步就是運(yùn)行 J2K。團(tuán)隊(duì)已經(jīng)能夠以無(wú)頭模式運(yùn)行 Android Studio 并調(diào)用 J2K,由此將整個(gè)管道作為腳本來(lái)運(yùn)行。

最后一步,對(duì)新的 Kotlin 文件進(jìn)行后處理。具體包括大部分自動(dòng)重構(gòu)與修復(fù)步驟,例如將 JUnit 規(guī)則標(biāo)記為 @JvmField。在此步驟中,團(tuán)隊(duì)還應(yīng)用了自動(dòng)更新 linter,并在無(wú)頭模式下應(yīng)用各種 Android Studio 建議。

“當(dāng)然,自動(dòng)化并不足以解決所有問(wèn)題,但至少能幫我們優(yōu)先處理那些最常見(jiàn)的問(wèn)題。”Strulovich 說(shuō)。

在 Java 重構(gòu)方面,Meta 使用的是 JavaASTParser 等工具,它能幫助解析某些類型。而在 Kotlin 這邊,團(tuán)隊(duì)還沒(méi)有找到能夠解析類型的好辦法,所以選擇使用 Kotlin 編譯器 API。

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

下一步

平均而言,Meta 發(fā)現(xiàn)遷移后的代碼行數(shù)減少了 11%。盡管網(wǎng)上各種案例引用的數(shù)字往往要比這高得多,但他們還是對(duì)這個(gè)數(shù)字感到滿意。

Strulovich 說(shuō),Meta 向 Kotlin 的遷移仍在進(jìn)行中并在加速。“Kotlin 仍然缺乏一些我們?cè)谑褂?Java 時(shí)已經(jīng)習(xí)慣了的工具和優(yōu)化,但我們正在努力縮小這些差距。隨著我們?nèi)〉玫倪M(jìn)展和這些工具和庫(kù)的成熟,我們也將努力把它們反饋給社區(qū)。”

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

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

分享到:
標(biāo)簽:Kotlin
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定