java - 如何在 Java 类中实现 Kotlin 挂起方法?

标签 java kotlin intellij-idea

我有一个Kotlin接口(interface)

interface MyKotlinInterface {
    suspend fun mySuspendableMethod(): List<String>
}

然后我创建了一个Java类,并实现了MyKotlinInterface

public class MyJavaImpl implements MyKotlinInterface {

    @Nullable
    @Override
    public Object mySuspendableMethod(@NotNull Continuation<? super List<? extends String>> completion) {
        return null;
    }
}

IDE 没有显示错误,但是当我编译时出现以下错误

error: MyJavaImpl is not abstract and does not override abstract method mySuspendableMethod(Continuation<? super List>) in MyKotlinInterface public class MyJavaImpl implements MyKotlinInterface {

所以我的问题是

  1. 这有可能吗?
  2. 如果不可能,为什么 IDE 不显示任何错误?以及为什么 IDE 将 suspend 方法转换为 Continuation 参数。

enter image description here

  1. 如果可能的话,为什么我会收到这个错误?以及如何解决?

更新:

我变了

@NotNull Continuation<? super List<? extends String>> completion

@NotNull Continuation completion

并且编译时错误消失了。

最佳答案

关于 suspend 方法如何在幕后在 Kotlin 中工作的最好 Material 可能是 Kotlin 存储库中的这个文件: https://github.com/JetBrains/kotlin/pull/3709/files

正如您正确指出的那样,suspend 关键字通知 Kotlin 编译器将函数转换为状态机,或者用更熟悉的术语来说,转换为回调链。

为了在回调之间传递信息,我们需要一些东西来保存先前计算的结果。这是您看到的 Continuation。在您的例子中,泛型类型是回调链中的最后一个调用应该产生的结果。

由于 JVM 中的泛型是一个编译时概念,因此通过完全删除它们可以规避问题,但并没有真正解决问题。

为什么 IDE 不警告编译问题?
AFAIK IntelliJ IDEA 使用自己的编译器版本来识别出现的问题。此编译器针对性能进行了优化,并且不处理某些边缘情况。

如何解决问题
在您的界面上放置一个类型:

interface MyKotlinInterface<T> {
    suspend fun mySuspendableMethod(): List<T>
}

您的 Java 类必须稍作更改:

public class MyJavaImpl<T> implements MyKotlinInterface<T> {

    @Nullable
    @Override
    public Object mySuspendableMethod(@NotNull Continuation<? super List<? extends T>> $completion) {
        return List.of("A", "B");
    }
}

但它会正常运行和编译:

fun main() = runBlocking {
    val impl = MyJavaImpl<String>()

    println(impl.mySuspendableMethod())
}

关于java - 如何在 Java 类中实现 Kotlin 挂起方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68032757/

相关文章:

java - Libgdx EXCEPTION_ACCESS_VIOLATION (0xc0000005)

java - 禁止用户同时从两个或多个 Android 设备登录

java - JPA : Mapping a OneToOne Long value (not an entity) to another tables column which is not a primary key

spring - Graphql工具:将实体类型映射到graphql类型

algorithm - 如何用Kotlin克隆链表?

java - 构建 java 应用程序后,某些 GUI 组件无法正常工作,但在 IDE 测试期间一切正常。为什么?

java - 如何获取员工 ID 并将其放入其他元素中

java - 像在收据中一样向 TextView 添加点

sql-server - 为什么 [PrtSc] 按钮在 Intellij-Idea 或 Microsoft SQL Server Management Studio 中不起作用?

intellij-idea - 如何在IDEA中粘贴代码而不重新格式化