接口bug中的Kotlin默认参数?

时间:2017-11-02 08:46:39

标签: kotlin

kotlin文件

interface Test {

    fun test(message: String, delay: Int =100)
}

class A: Test
{
    override fun test(message: String, delay: Int) {
    }

}

我发现我不能在界面或类中使用@JvmOverloads

如果我在界面中添加@JvmOverloads,则错误为@JvmOverloads annotation cannot be used on interface method,如果我在课程中添加@JvmOverloads,则错误为platform declaration clash....

但是,我似乎能够在kotlin文件中使用默认参数,就像这样。

var a=A()
a.test("1234")

但是当我在java文件中使用它时,似乎该方法没有重载。

A a=new A();
a.test("123");//Compile error

以下没有界面的版本可以使用

class A
{
    @JvmOverloads
     fun test(message: String, delay: Int=100) {
    }

}

然后我可以在java文件中正常使用它

 A a=new A();
 a.test("123");

但是如何在添加界面后保持相同的功能?

2 个答案:

答案 0 :(得分:7)

这不是错误。 @JvmOverloads注释根本不适用于抽象方法。

来自Kotlin docs:

  

通常,如果您使用默认参数值编写Kotlin函数,它将仅在Java中显示为完整签名,并且所有参数都存在。如果您希望向Java调用者公开多个重载,可以使用@JvmOverloads注释。

     

注释也适用于构造函数,静态方法等。它不能用于抽象方法,包括接口中定义的方法

来源:https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#overloads-generation

为什么呢? 因为您可以从我提到的文档中学习,@JvmOverloads指示编译器生成大量Java重载方法,从最后一个开始逐个省略每个参数。 据我所知,每个重载方法都会在内部调用一个参数,而这个附加参数都有默认值。编辑:请参阅@hotkey here的评论

这不适用于抽象方法,因为它们没有任何主体。 此外,新的Java接口将拥有更多方法,其实现必须实现所有这些方法。 Kotlin界面只有一种方法。

答案 1 :(得分:0)

要获得相同的结果,您可以在Kotlin中创建一个LegacySupport类,该类实际上将使用默认参数调用该函数,然后只能将该函数的返回结果从该类公开给java类。