kotlin汇总10-Java调用kotlin

来源:互联网 发布:ubuntu des 解密 编辑:程序博客网 时间:2024/06/05 02:43

Java可以很容易的调用kotlin代码

1属性

比如kotlin有var firstName: String
其实等同于在Java中下面的定义

private String firstName;public String getFirstName() {    return firstName;}public void setFirstName(String firstName) {    this.firstName = firstName;}

2.Package-Level函数

kotlin代码

// example.ktpackage democlass Foofun bar() {}

在Java调用如下

// Javanew demo.Foo();demo.ExampleKt.bar();

可以通过@file:JvmName注释告诉Java,比如

//kotlin代码@file:JvmName("DemoUtils")package democlass Foofun bar() {}

//Java调用

// Javanew demo.Foo();demo.DemoUtils.bar();

如果在同一自动生成的类(包名和类名一致)囊括了多个kotlin文件则需要使用@file:JvmMultifileClass,比如

// oldutils.kt@file:JvmName("Utils")@file:JvmMultifileClasspackage demofun foo() {}// newutils.kt@file:JvmName("Utils")@file:JvmMultifileClasspackage demofun bar() {}

在Java中调用

// Javademo.Utils.foo();demo.Utils.bar();

3.对象实例的字段(fields)

可以通过@JvmField修饰,比如

//kotlinclass C(id: String) {    @JvmField val ID = id}
// Javaclass JavaClient {    public String getID(C c) {        return c.ID;    }}

4.静态字段

4.1 使用@JvmField修饰

//kotlinclass Key(val value: Int) {    companion object {        @JvmField        val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }    }}
// JavaKey.COMPARATOR.compare(key1, key2);// public static final field in Key class

4.2使用lateinit修饰

//kotlinobject Singleton {    lateinit var provider: Provider}
// JavaSingleton.provider = new Provider();// public static non-final field in Singleton class

4.3使用const修饰

//kotlin// file example.ktobject Obj {    const val CONST = 1}class C {    companion object {        const val VERSION = 9    }}const val MAX = 239
//javaint c = Obj.CONST;int d = ExampleKt.MAX;int v = C.VERSION;

5.静态方法

通过@JvmStatic修饰

//kotlinclass C {    companion object {        @JvmStatic fun foo() {}        fun bar() {}    }}//javaC.foo(); // works fineC.bar(); // error: not a static methodC.Companion.foo(); // instance method remainsC.Companion.bar(); // the only way it works
//kotlinobject Obj {    @JvmStatic fun foo() {}    fun bar() {}}//javaObj.foo(); // works fineObj.bar(); // errorObj.INSTANCE.bar(); // works, a call through the singleton instanceObj.INSTANCE.foo(); // works too

6.可见域

  • kotlin的private成员函数变成java的private成员函数
  • kotlin的private顶级声明(直接在kotlin文件下面)变成java的包可见声明
  • kotlin的protected在Java还是一样,但是需要注意的是Java的protected可以访问同一个包下面的所有,但是kotlin是private+子类可见,所以明显Java的protected可见域比kotlin要大
  • kotlin的internal变成java的public
  • kotlin的public变成Java的public

7.KClass

有些时候需要从KClass类型中获取Kotlin方法,但是Class不等于KClass,所以你需要如下

kotlin.jvm.JvmClassMappingKt.getKotlinClass(MainView.class)

8.使用@JvmName处理签名冲突

比如下面

fun List<String>.filterValid(): List<String>fun List<Int>.filterValid(): List<Int>

上面两个在Jvm的签名都是一样的:filterValid(Ljava/util/List;)Ljava/util/List;
所以需要区分,使用@JvmName

fun List<String>.filterValid(): List<String>@JvmName("filterValidInt")fun List<Int>.filterValid(): List<Int>//在Java中调用filterValidfilterValidInt

一个同样的例子

val x: Int    @JvmName("getX_prop")    get() = 15fun getX() = 10

9.生成覆载方法

比如,有kotlin代码

fun f(a: String, b: Int = 0, c: String = "abc") {    ...}//调用f(a)f(a, b)f(a, b, c)

要想在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) { }

10.检查异常

比如有kotlin代码

// example.ktpackage demofun foo() {    throw IOException()}//我们希望在java如下调用// Javatry {  demo.Example.foo();}catch (IOException e) { // error: foo() does not declare IOException in the throws list  // ...}

需要如下添加@Throws注释,如下

@Throws(IOException::class)fun foo() {    throw IOException()}

11.Null安全

不保证

12.变体泛型

如下kotlin代码

class Box<out T>(val value: T)interface Baseclass Derived : Basefun boxDerived(value: Derived): Box<Derived> = Box(value)fun unboxBase(box: Box<Base>): Base = box.value//可以天真的用下面的Java代码代替Box<Derived> boxDerived(Derived value) { ... }Base unboxBase(Box<Base> box) { ... }//但是有个问题,unboxBase(boxDerived("s")) 这行代码可以在kotlin没问题,因为Box<Derived>是Box<Base>的子类型(注意out修饰了泛型),但是在Java,我们知道肯定报错的。所以Base unboxBase(Box<Base> box) { ... }//ERROR,要改成如下Base unboxBase(Box<? extends Base> box) { ... } //这样就可以使用unboxBase(boxDerived("s"))

13.Nothing的转化

//kotlinfun emptyList(): List<Nothing> = listOf()// is translated to JavaList emptyList() { ... }