java中調(diào)用kotlin代碼

在上一篇博客中,介紹了kotlin調(diào)用java代碼,這篇文章介紹java調(diào)用kotlin代碼。

屬性

kotlin屬性被編譯成如下java元素:

- 一個(gè)getter方法,方法名為屬性名加上get前綴。

- 一個(gè)setter方法,方法名為屬性名加上set前綴(只針對var修飾的變量屬性有效)

- 一個(gè)私有域,名字和屬性名相同

例如,var firstName:String被編譯成如下java聲明:

private String firstName;

public String getFirstName(){

? ?return firstName;

}

public void setFirstName(String firstName){

? ?this.firstName=firstName;

}

如果屬性名字以'is'起始,那么我們采用另一種命名映射方式:getter方法的名字和屬性名字一樣,setter方法的名字會將屬性中的is替換為set。例如,對于isOpen屬性,getter調(diào)用名為isOpen(),setter調(diào)用名為setOpen()。這條規(guī)則適用于任何認(rèn)為類型的屬性,而不僅僅是Boolean類型。

包級別的函數(shù)

所有的聲明在org.foo.bar包中example.kt文件的函數(shù)和屬性,都會被編譯成名為org.foo.bar.ExampleKt的Java類的靜態(tài)方法。

//example.kt

package demo

class Foo

fun bar(){

}

//Java

new demo.Foo();

demo.ExampleKt.bar();

生成的java類的名字可以用@JvmName注解來指定:

@file:JvmName("DemoUtils")

package demo

class Foo

fun bar(){

}

//Java

new demo.Foo();

demo.DemoUtils.bar();

當(dāng)存在許多生成同一個(gè)java類名的文件時(shí),通常是個(gè)錯(cuò)誤。然而,編譯器有能力生成一個(gè)單獨(dú)的java類包含所有要生成這個(gè)Java類的kotlin文件中聲明的屬性。通過在所有此類文件中使用@JvmMultifileClass注解來允許這種集成。

//oldutils.kt

@file:JvmName("Utils")

@file:JvmMultifileClass

package demo

fun foo(){

}

//newutils.kt

@file:JvmName("Utils")

@file:JvmMultifileClass

package demo

fun bar(){

}

//Java

demo.Utils.foo();

demo.Utils.bar();

靜態(tài)方法

上文中提到過,kotlin將包級別的函數(shù)展示為靜態(tài)方法。Kotlin同樣可以將命名對象或伴生對象的方法生成靜態(tài)方法,如果你用@JvmStatic注解標(biāo)注這些方法。如果你使用這個(gè)注解,編譯器會同時(shí)在封閉類中生成一個(gè)靜態(tài)方法,也在對象本身生成一個(gè)靜態(tài)方法。例如:

class C{

? ? companion object{

? ? ? ? ?@JvmStatic fun foo(){}

? ? ? ? ?fun bar(){}

}

}

現(xiàn)在,foo()是java中的靜態(tài)方法,但是bar()不是。

重載函數(shù)

正常情況下,如果你的kotlin方法含有默認(rèn)參數(shù)值,在java中只會看到其全部簽名,包含所有的參數(shù)。如果你希望暴露多個(gè)重載給java調(diào)用者,可以使用@JvmOverloads注解。

@JvmOverloads fun f(a:String,b:Int=0,c:String="abc"){

}

對于每個(gè)帶有默認(rèn)值的參數(shù),這回生成一個(gè)額外的重載方法,這個(gè)方法會移除包含有這個(gè)參數(shù)的這個(gè)參數(shù)右邊所有參數(shù)列表。在這個(gè)例子中,會生成如下的方法:

//Java

void f(String a,int b,String c){}

void f(String a,int b){}

void f(String a){}

這個(gè)注解對于構(gòu)造方法和靜態(tài)方法同樣有效,但是不能適用于抽象方法,包括接口聲明的方法。

受檢異常

如上文所述,kotlin沒有受檢異常。因此,java簽名的kotlin方法不拋出異常,如果我們有如下的方法:

//example.kt

fun foo(){

? ? ? ?throw IOException()

}

我們想在java調(diào)用這個(gè)方法并且捕獲異常:

//Java

try{

demo.Example.foo();

}catch(IOException e){ //產(chǎn)生錯(cuò)誤:foo()沒有在拋出列表中聲明IOException

? ? //..

}

為了解決這個(gè)問題,在kotlin中使用@Throws注解:

@Throws(IOException::class)

fun foo(){

throw IOException()

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容