java中调用kotlin代码

2017-06-26  本文已影响0人  洋spark

在上一篇博客中,介绍了kotlin调用java代码,这篇文章介绍java调用kotlin代码。

属性

kotlin属性被编译成如下java元素:

- 一个getter方法,方法名为属性名加上get前缀。

- 一个setter方法,方法名为属性名加上set前缀(只针对var修饰的变量属性有效)

- 一个私有域,名字和属性名相同

例如,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调用名为isOpen(),setter调用名为setOpen()。这条规则适用于任何认为类型的属性,而不仅仅是Boolean类型。

包级别的函数

所有的声明在org.foo.bar包中example.kt文件的函数和属性,都会被编译成名为org.foo.bar.ExampleKt的Java类的静态方法。

//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();

当存在许多生成同一个java类名的文件时,通常是个错误。然而,编译器有能力生成一个单独的java类包含所有要生成这个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();

静态方法

上文中提到过,kotlin将包级别的函数展示为静态方法。Kotlin同样可以将命名对象或伴生对象的方法生成静态方法,如果你用@JvmStatic注解标注这些方法。如果你使用这个注解,编译器会同时在封闭类中生成一个静态方法,也在对象本身生成一个静态方法。例如:

class C{

    companion object{

         @JvmStatic fun foo(){}

         fun bar(){}

}

}

现在,foo()是java中的静态方法,但是bar()不是。

重载函数

正常情况下,如果你的kotlin方法含有默认参数值,在java中只会看到其全部签名,包含所有的参数。如果你希望暴露多个重载给java调用者,可以使用@JvmOverloads注解。

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

}

对于每个带有默认值的参数,这回生成一个额外的重载方法,这个方法会移除包含有这个参数的这个参数右边所有参数列表。在这个例子中,会生成如下的方法:

//Java

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

void f(String a,int b){}

void f(String a){}

这个注解对于构造方法和静态方法同样有效,但是不能适用于抽象方法,包括接口声明的方法。

受检异常

如上文所述,kotlin没有受检异常。因此,java签名的kotlin方法不抛出异常,如果我们有如下的方法:

//example.kt

fun foo(){

       throw IOException()

}

我们想在java调用这个方法并且捕获异常:

//Java

try{

demo.Example.foo();

}catch(IOException e){ //产生错误:foo()没有在抛出列表中声明IOException

    //..

}

为了解决这个问题,在kotlin中使用@Throws注解:

@Throws(IOException::class)

fun foo(){

throw IOException()

}

上一篇下一篇

猜你喜欢

热点阅读