這篇文章主要介紹了Java與Kotlin之間怎樣進行互操作,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)專注于雨湖網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供雨湖營銷型網(wǎng)站建設(shè),雨湖網(wǎng)站制作、雨湖網(wǎng)頁設(shè)計、雨湖網(wǎng)站官網(wǎng)定制、小程序設(shè)計服務(wù),打造雨湖網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供雨湖網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
前言
目前kotlin是谷歌首推的開發(fā)Android的語言,但由于歷史原因,我們絕大部分項目依舊還是以Java為主的,也就是說存在Java和Kotlin兩種語言同時開發(fā)的情況。
有人會說把老項目全部翻譯成Kotlin,的確可以怎么做,但是成本還是挺大的。我們只能一點一點慢慢的向kotlin語言遷移。
那么在遷移的過程中就避免不了Java和Kotlin相互調(diào)用的情況。即Kotlin調(diào)用Java或者Java調(diào)用Kotlin。下面我們就來具體看下兩者之間相互操作的一些解決方案。
kotlin調(diào)用java
可空性(Nullability)
Java默認有數(shù)值可空性而kotlin沒有,所以在調(diào)用Java的方法的時候不知道會不會收到空值。
所以我們在Kotlin中調(diào)用Java的時候需要添加 ?或者 !來告訴Kotlin有可能出現(xiàn)空值。
比如這里有一個Java方法,接受一組字符串后返回一組做字符串:
public Set<String> toSet(Collection<String> elements){ //TODO }
那么Kotlin在調(diào)用的時候是不能確定輸入和輸出是否可為空的。就需要使用?或者 !來輔助判斷。
為了方便Kotlin調(diào)用,我們通常使用 @NotNull 注解來標識Java代碼的非原始參數(shù)、字段、返回值。
@NotNull Set<@NotNull String> toSet(@NotNull Collection<@NotNull String> elements){ //TODO }
這個Kotlin在調(diào)用的時候就明確知道不能為空,這里我們使用的是jetBrain的 @NotNull注解,當然還有其他選擇,如下圖:
這里還是推薦使用JetBrain或者Android的注解。
前綴屬性:(getter、setter)
如果是使用Java bean,那么我們在Kotlin中調(diào)用就沒有什么問題。
如果你的空參數(shù)方法是以get開頭的,那么Kotlin就知道這是getter,就可以通過屬性名來訪問它。
相同的如果是由set開頭的單一參數(shù)方法,那么Kotlin就知道這是setter,就通過屬性名直接賦值。
當然is的工作原理也是和它們類似的。
我們定義一個Java bean:
class User { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Kotlin中訪問
val user = User() user.name = "四爺" //賦值 val age = user.age //獲取age字段值
關(guān)鍵字(keywords)
kotlin中有很多系統(tǒng)定義的關(guān)鍵字如 fun is in objects、typeof、val、var、when、typealias等。
這些關(guān)鍵字在java是可以被使用的,但是在kotlin卻是不行的。
函數(shù)或者參數(shù)使用了這些關(guān)鍵字,那么kotlin在調(diào)用的時候會出現(xiàn)一些問題,比如Java中定義了一個方法名叫 is 的方法。那么在Kotlin中直接調(diào)用就會報錯。
那么最簡單的方法就是重命名Java方法,但如果調(diào)用的是三方庫的方法,就很難去重命名了。
所以我們另一種解決方式是在Kotlin調(diào)用java方法的時候加上 `` 反引號來使用。
Utils.`is`()
但是我們?nèi)绻苤孛€是重命名,以防止代碼出現(xiàn)太多的符號。
避免在任何擴展方法和擴展屬性上使用Any
運算符重載(operator Overloading)
在Java不存在運算符重載,而kotlin有。比如:
a+b => a.plus(b)
在kotlin中將運算符 + 翻譯為了方法 plus。
如果在Java中使用了同樣的方法名稱,比如 加(plus)、 減(minus)或者其他運算符名稱,那么請務(wù)必確保他們與運算符兼容,避免意外調(diào)用他們。
Java調(diào)用Kotlin
JvmName & JvmMultifileClass
當我們在遷移的時候會將Java的工具類翻譯為Kotlin拓展函數(shù)或者頂層函數(shù)。但是這樣處理之后,在Java文件中是無法直接調(diào)用的,此時我們需要加注解 @file:JvmName(“文件名稱”):
Ext.kt文件
@file:JvmName("ExtUtils") package com.demo.javaAndKotlin fun a(): String { ... } fun b(): String { ... }
這里我們將名稱命名為ExtUtils。此外,我們可能還有其他的頂層函數(shù)或者擴展函數(shù)。按照上面這種方式我們也可以指定一個其他的名稱,但是如果我們也想使用ExtUtils這個名稱的時候會報錯:
Duplicate JVM class name
此時我們需要在不同的文件中加入新的注解 @file:JvmMultifileClass 。意思是將所有的文件合并到一個新的名稱為ExtUtils文件中。
ExtOther.kt文件
@file:JvmMultifileClass @file:JvmName("ExtUtils") package com.demo.javaAndKotlin fun c(str: Any): String { ... }
我們在Ext.kt文件中也加入@file:JvmMultifileClass注解,我們就可以在Java文件中直接使用ExtUtils來調(diào)用 a(),b(),c()方法了。
JvmField
在 kotlin中我們使用的數(shù)據(jù)類即 data class 是不需要指定getter和setter的,可以直接通過字段名來訪問它們。但是如果是在Java文件中調(diào)用data class依舊是需要使用getter和setter方法進行調(diào)用的。這里我們是可以修改他們的,那就是使用 @JvmField 注解,通過注解,可以直接將字段暴露出去進行訪問。
data class Person( @JvmField var name: String, @JvmField var age: Int ) //java中調(diào)用 Person person = new Person("",1); person.name = ""; person.age = 10;
但是也有例外就是lateinit修飾的字段會自動暴露,無需指定@JvmField注解。還有const修飾的字段也是一樣會自動暴露。
另外,如果我們想在Java中調(diào)用setName的時候修改這個屬性名稱不叫setName,這里我們需要使用@set:JvmName 注解。同理修改getName使用@get:JvmName 。需要注意的是,指定了@set:JvmName或者@get:JvmName注解后不需要在指定@JvmField了。
data class Person( @set:JvmName("changeName") var name: String, @JvmField var age: Int, @get:JvmName("likesPink") var likesPink: Boolean ){ lateinit var address:String }
JvmStatic
當我們將Java文件的靜態(tài)方法遷移到Kotlin中時,我們會將其放在 companion object中,但是這樣處理之后在Java文件中無法直接調(diào)用,得通過companion對象實例方法來調(diào)用。
class MyService { internal fun doWork() { ... } companion object { fun schedule(context: Context) { ... } } } //在Java中調(diào)用 MyService.Companion.schedule(this);
幸運的是Kotlin提供了 @JvmStatic 注解。他會讓Kotlin在編譯器完成類封裝后生成一個靜態(tài)方法。
class MyService { internal fun doWork() { ... } companion object { @JvmStatic fun schedule(context: Context) { ... } } } //在Java中調(diào)用 MyService.schedule(this);
JvmOverloads
在Kotlin中我們可以給函數(shù)的參數(shù)設(shè)置默認值,即默認參數(shù)。但是這個功能在Java中是沒有的。如果不做任何處理,那么在Java中調(diào)用函數(shù)的時候,就必須每個參數(shù)都要傳入。那么我們設(shè)置的默認參數(shù)就沒有任何意義了。
所以,Kotlin給我們提供了 @JvmOverloads注解,使用這個注解后,會讓Kotlin編譯器按照從左向右的順序依次為每一個可選參數(shù)生成重載。
@JvmOverloads fun Bitmap.resize(width: Int, height: Int = 200) { } //java調(diào)用 ExtUtils.resize(bitmap,100);
這里我們在Kotlin中很容易就理解了Bitmap.resize方法的含義,但是ExtUtils.resize這樣調(diào)用的時候,方法名不夠明確。所以我們可以使用@JvmName注解來指定名稱。
@JvmName("resizeBitmap") @JvmOverloads fun Bitmap.resize(width: Int, height: Int = 200) { } //java調(diào)用 ExtUtils.resizeBitmap(bitmap,100);
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java與Kotlin之間怎樣進行互操作”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
網(wǎng)站欄目:Java與Kotlin之間怎樣進行互操作
網(wǎng)頁網(wǎng)址:http://www.rwnh.cn/article6/gopiig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、做網(wǎng)站、手機網(wǎng)站建設(shè)、電子商務(wù)、自適應(yīng)網(wǎng)站、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)