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

apache64

我有一个Kotlin界面

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 没有显示错误,但是当我编译时出现以下错误

错误:MyJavaImpl 不是抽象的,并且不会覆盖 MyKotlinInterface 公共类中的抽象方法 mySuspendableMethod(Continuation<? super List>) MyJavaImpl 实现 MyKotlinInterface {

所以我的问题是

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

在此处输入图片说明

  1. 如果可能,为什么我会收到此错误?我该如何解决?

更新:

我变了

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

@NotNull Continuation completion

并且编译时错误消失了。

阿列克谢·索申

suspendKotlin 存储库中的这个文件可能是关于如何在 Kotlin 后台工作的最佳材料https : //github.com/JetBrains/kotlin/pull/3709/files

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

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

由于 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())
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章