Kotlin基本語法之(九)Kotlin與java互操作

實(shí)際開發(fā)我們即使決定切換到Kotlin語言,但由于歷史模塊或依賴的第三方庫仍是使用Java開發(fā)的,這也就不可避免在二者之前產(chǎn)生相互調(diào)用,雖然官方宣稱100%兼容,但實(shí)際使用過程中仍有一些小問題需要注意。

Kotlin調(diào)用Java

get/set方法

由于Kotlin中并不需要顯式的聲明get/set方法,所以對于訪問Java標(biāo)準(zhǔn)實(shí)體類中的屬性,可直接通過屬性名稱。

Animal.java
public class Animal {
    private int age;
    private String name;

    public Animal(int age, String name) {
        this.age = age;
        this.name = name;
    }
    //...getter/setter
}

kotlin中這樣使用

val animal = Animal(3, "twodog")
println(animal.age)//讀取
animal.name = "dahuang"http://修改

獲取Java類型

若想獲取某個(gè)java類的類型需通過Kotlin的反射實(shí)現(xiàn)。::得到Kotlin類型,繼續(xù)調(diào)用擴(kuò)展屬性java得到其對應(yīng)的java類型。

val animal = Animal(3, "twodog")
println(animal::class.java.simpleName)
//輸出
Animal

wait/notify

我們知道kotlin中Any與Java中的Object對應(yīng),但問題是Any類中只有equals/hashCode/toString三個(gè)方法。

public open class Any {

    public open operator fun equals(other: Any?): Boolean

    public open fun hashCode(): Int

    public open fun toString(): String
}

那并發(fā)編程用到的等待喚醒wait/notify方法如何使用呢?事實(shí)上官方不建議使用普通對象鎖,取而代之的是Lock鎖。如果你確實(shí)想使用可以通過下面的方法。

(foo as java.lang.Object).wait()

即先強(qiáng)轉(zhuǎn)為java的Object類型,再使用并發(fā)函數(shù)。

Java調(diào)用Kotlin

get/set方法

java訪問Kotlin的屬性應(yīng)使用對用的getter/setter方法。

//Client.kt
data class Client(var name: String)

//java test
Client client = new Client("zhangsan");
System.out.println(client.getName());
client.setName("lisi");

另外,Kotlin中默認(rèn)會(huì)給屬性添加getter/setter方法(val類型的沒有setter),這勢必會(huì)造成一定的性能損耗,可為屬性添加@JvmField注解去掉此默認(rèn)行為。

//去掉NO屬性的getter/setter
data class Client(var name: String,@JvmField  var NO: Int) 

頂級函數(shù)

之前章節(jié)講到頂級函數(shù)是用靜態(tài)方法實(shí)現(xiàn)的,而該靜態(tài)方法所在的類為kotlin文件名+Kt。

// TestPackageMethod.kt
fun sayHello(name: String) {
    println("hello $name")
}
//java test
TestPackageMethodKt.sayHello("zhao");

如果想改變生成的默認(rèn)類名,可以在kt文件中package聲明前添加注解。

//改變默認(rèn)生成的Java類名
@file:JvmName("MyPackageMethodTest")

object靜態(tài)函數(shù)

之前講到object類為單例類,內(nèi)部實(shí)現(xiàn)是通過餓漢式實(shí)現(xiàn)單例,在類中有一個(gè)本類的靜態(tài)實(shí)例,因此當(dāng)在java中訪問此object類中方法的時(shí)需通過此靜態(tài)實(shí)例,該實(shí)例的默認(rèn)名字統(tǒng)一為INSTANCE。

//ObjectTest.kt
object ObjectTest {
    fun objectMethod() {
    }
}

//java call
ObjectTest.INSTANCE.objectMethod();

伴生對象

伴生對象同樣是通過靜態(tài)實(shí)現(xiàn),只不過靜態(tài)方法在一個(gè)Companion內(nèi)部類中,因此Java調(diào)用需顯示聲明Companion類名。

//TestStatic.kt
open class TestStatic {
    companion object {
        fun create(): TestStatic {
            return TestStatic()
        }
    }
}

//java call
TestStatic.Companion.create()

異常檢查

與Java語言非常大的不同是Kotlin不做異常檢查,這就導(dǎo)致在Java中聲明的檢查異常不需在Kotlin代碼中捕獲,從而發(fā)生意想不到的崩潰,反之亦然。

//TestKotlinException.kt
object TestKotlinException {
    //拋出異常但方法不需異常聲明
    fun getException() {
        throw Exception("I am an exception in kotlin")
    }
}

//java call
public static void testException() {
    //編譯通過 但運(yùn)行會(huì)發(fā)生異常
    TestKotlinException.INSTANCE.getException();
}

如果想改變此默認(rèn)行為,我們需要在Kotlin方法前添加@Throws(Exception::class)注解。

@Throws(Exception::class)
fun getException() {
    throw Exception("I am an exception in kotlin")
}

此時(shí)java調(diào)用端會(huì)出現(xiàn)期望的編譯錯(cuò)誤。

//unhandled exception: java.lang.Exception
TestKotlinException.INSTANCE.getException();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容