从 Java 访问 Kotlin 扩展函数

2022-08-31 05:54:06

是否可以从 Java 代码访问扩展函数?

我在 Kotlin 文件中定义了扩展函数。

package com.test.extensions

import com.test.model.MyModel

/**
 *
 */
public fun MyModel.bar(): Int {
    return this.name.length()
}

其中 是一个(生成的)java 类。现在,我想在我的普通java代码中访问它:MyModel

MyModel model = new MyModel();
model.bar();

但是,这不起作用。IDE 将无法识别 bar() 方法,编译将失败。

工作原理是与 kotlin 中的静态函数一起使用:

public fun bar(): Int {
   return 2*2
}

通过使用,我的IDE似乎配置正确。import com.test.extensions.ExtensionsPackage

我从kotlin文档中搜索了整个Java-interop文件,也搜索了很多,但我找不到它。

我做错了什么?这有可能吗?


答案 1

默认情况下,文件中声明的所有 Kotlin 函数都将编译为同一包中某个类中的静态方法,并且名称派生自 Kotlin 源文件(第一个字母大写,“.kt”扩展名替换为“Kt”后缀)。为扩展函数生成的方法将具有附加的第一个参数,其中包含扩展函数接收器类型。

将其应用于原始问题,Java编译器将看到名为example.kt的Kotlin源文件。

package com.test.extensions

public fun MyModel.bar(): Int { /* actual code */ }

就好像声明了以下 Java 类一样

package com.test.extensions

class ExampleKt {
    public static int bar(MyModel receiver) { /* actual code */ }
}

从 Java 的角度来看,由于扩展类不会发生任何变化,因此您不能仅使用点语法来访问此类方法。但它们仍然可以作为普通的Java静态方法调用:

import com.test.extensions.ExampleKt;

MyModel model = new MyModel();
ExampleKt.bar(model);

静态导入可用于示例Kt类:

import static com.test.extensions.ExampleKt.*;

MyModel model = new MyModel();
bar(model);

答案 2

Kotlin 顶级扩展函数被编译为 Java 静态方法。

给定 Kotlin 文件在包中包含:Extensions.ktfoo.bar

fun String.bar(): Int {
    ...
}

等效的 Java 代码是:

package foo.bar;

class ExtensionsKt {
    public static int bar(String receiver) { 
        ...
    }
}

除非,即包含该行Extensions.kt

@file:JvmName("DemoUtils")

在这种情况下,Java 静态类将被命名为DemoUtils

在 Kotlin 中,扩展方法可以用其他方式声明。(例如,作为成员函数或作为伴随对象的扩展。


推荐