Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin default arguments in interface bug?

Tags:

kotlin

kotlin file

interface Test {

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

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

}

I find i can't use @JvmOverloads in interface nor class.

if i add a @JvmOverloads in interface,the error is @JvmOverloads annotation cannot be used on interface method,if i add @JvmOverloads in class,the error is platform declaration clash....

However, I seem able to use defaults paramters in kotlin files,like this.

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

But when I use it in a java file, it seems that the method is not overloaded。

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

The following version without interface can work

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

}

Then I can use it normally in java file

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

But how to maintain the same functionality after add the interface?

like image 448
BlackCat Avatar asked Nov 02 '17 08:11

BlackCat


1 Answers

This is not a bug. @JvmOverloads annotation simply does not work with abstract methods.

From Kotlin docs:

Normally, if you write a Kotlin function with default parameter values, it will be visible in Java only as a full signature, with all parameters present. If you wish to expose multiple overloads to Java callers, you can use the @JvmOverloads annotation.

The annotation also works for constructors, static methods etc. It can't be used on abstract methods, including methods defined in interfaces.

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

Why? Because as You can learn from the doc I mentioned, @JvmOverloads instructs compiler to generate bunch of Java overloaded methods, omitting each of the parameters one by one, starting from the last one. As far as I understand, each overloaded method calls internally method with one more parameter, and this additional parameter has default value. Edit: see comment by @hotkey here

This won't work with abstract methods, because they don't have any body. Also new Java interface would have more methods, and its implementations would have to implement all of them. Kotlin interface had only one method.

like image 134
3voC Avatar answered Nov 09 '22 20:11

3voC