写点什么

浅谈 Kotlin 与 Java 互操作 (下)

作者:子不语Any
  • 2022-11-30
    湖南
  • 本文字数:2120 字

    阅读完需:约 7 分钟

浅谈Kotlin与Java互操作(下)

前言

Kotlin is 100% interoperable with Java and Android


Kotlin 官网的一句标语,其旨意是表达 kotlin 的Interoperable-互操作特性


互操作就表示 Kotlin 中可以调用 Java 的开放接口来访问成员属性和成员方法,同时在 Java 代码中也百分百兼容 Kotlin 代码,本篇就来探讨一下 Java 调用 Kotlin。

文章概览

调用 Kotlin 中“Static” fields,“Static” methods

Java 中,用关键字 static 来修饰静态方法和字段,直接通过"类名.属性名"进行访问。而 Kotlin 中没有 static 关键字,但可以用伴生对象(companion object)方式设置字段或者方法。


Java 中调用时,可通过 类型.成员类名.伴生对象.成员 的方式访问,用以下示例:


创建 Department 类并声明一个名为 Fruit 伴生对象,该对象中有静态字段 name,用注解 @JvmStatic修饰方法 sayHello()


class Department {    companion object Fruit {        var name = "Apple" // 静态字段        @JvmStatic        fun sayHello() {  // 静态方法             println(name)        }    }}
复制代码


上述代码,伴生对象中包含一个静态字段 name,用注解@JvmStatic声明一个静态方法 sayHello()


在 Java 中调用 Kotlin 伴生对象的字段和方法:


public class Demo {    public static void main(String[] args) {        Department.Fruit.setName("Any"); // 类名.伴生对象.成员 的方式访问             Department.Fruit.sayHello();             Department.sayHello();           // 类名.成员方法 的访问方式    }}
复制代码


运行结果:


AnyAny
复制代码


上面示例,Java 可通过 类名.伴生对象名.getXX()/setXX() 来访问 Kotlin 静态字段,通过 类名.伴生对象.方法名类名.方法名 来访问 Kotlin 中静态方法。

调用 Kotlin 中 Instance fields

Java 中,访问某个字段,一般通过 getXX()/setXX()方法来获取,在 Kotlin 中,是通过对象.字段名来获取。


在 Java 中将 Kotlin 属性公开,要使用@JvmField对其进行修饰, 官方文档上对该字段的约束:


  • 不是私有的

  • 没有 或 修饰符是open override const

  • 不是委托属性


class User(id: String) {     @JvmField val ID = id }
复制代码


上述代码中,给 ID 字段添加了@JvmField注解,可以使 ID 字段在 Java 中直接以对象.ID 的方式访问


// Java class JavaClient {     public String getID(User user) {         return user.ID;     } }
复制代码

调用 Kotlin 中 Package-level functions

Kotlin 中的包级函数:在包中直接声明的函数,它在编译时最终会生成一个静态的函数,Java 中调用该函数有方式:


  • 包级函数所在文件会生成名为“文件名 Kt”的类,以 文件名 Kt.函数名() 的形式调用包级函数

  • 若要编译包级函数的类名(改成与 Java 类名类似),则需在 Kotlin 文件添加@file:JvmName("类名")的注解


示例 1


// app.kt package org.example class Util fun getTime() { /*...*/ }
复制代码


在 Java 中调用上述声明的方法和类,文件名 Kt.函数名() 的形式调用


// Java new org.example.Util(); org.example.AppKt.getTime();
复制代码


示例 2 若要生成设置自定义名称的 Java 类,请使用注释:@JvmName


@file:JvmName("DemoUtils") package org.example class Util fun getTime() { /*...*/ }
复制代码


在 Java 中则通过自定义的类名调用


// Java new org.example.Util(); org.example.DemoUtils.getTime();
复制代码


注意

在 Java 中不可通过 new 关键字来创建 Kotlin 中编译后的 PackageFunctionKt 类的对象

关键字冲突

一些 Java 中的常规标识符,确是 Kotlin 关键字,如 in、Object、is 等。Java 中使用 Kotlin 中的关键字作为方法名,则需要用反引号字符转义来调用。\


Keyword Java class 中声明一个 is()方法


public class Keyword {    public boolean is(Object o) { // 声明 is方法        return true;    }}
复制代码


在 Kotlin 中,调用上述 Java 代码中创建的 is()方法


fun main() {    var key = Keyword()     // 声明对象    var result = key.`is`("key")  // 通过反引号转义再调用is()    println(result)}
复制代码


运行结果:


true
复制代码


在上述代码中,由于在 Kotlin 中 is 是关键字,若想要调用 is()方法,则需通过反引号转义来实现调用。

调用 Kotlin 中集合类

Kotlin 中的 List 和 MutableList 映射到 Java 中的 List 类型,Map 和 Set 也类似,需注意的点:通过 listof()方法创建的集合是不能扩展或删除元素。


Klist.kt 中声明 getList()方法,返回值是一个集合,通过 listof()方法创建。


fun getList():List<String>{   return listOf("沐小琪","小汤圆","沐沐")}
复制代码


在 Java 中通过调用上述 Kotlin 的 getList()来获取 List 集合并修改元素


public class Demo {    public static void main(String[] args) {        List<String> list = ListKt.getList();  // 映射到List        list.set(2, "子不语Any");                   // 修改集合中下标为2的元素        for (int i = 0; i < list.size(); i++) {            System.out.println(list.get(i));        }   }}
复制代码


运行结果:


沐小琪小汤圆子不语Any
复制代码


在上述代码中,通过 set()方法修改 list 集合中下标为 2 的元素。


需注意:Java 中可以通过 add()方法向集合中添加或修改元素,但此处不可这样写,不然在运行时报错


以上是总结平常开发中 Java 调用 Kotlin 代码的情形,需要了解更详细可以参看 Kotlin 官方文档。

发布于: 刚刚阅读数: 3
用户头像

子不语Any

关注

If not now,when? 2022-09-17 加入

安卓攻城狮

评论

发布
暂无评论
浅谈Kotlin与Java互操作(下)_android_子不语Any_InfoQ写作社区