androidkotlinoverloadingdefault-arguments

How @JvmOverloads work on Kotlin when using default arguments?


I want to understand how to use JvmOverloads annotation better and how to handle kotlin default arguments in java in a better way.

Imagine I have a function like this:

@JvmOverloads
@JvmStatic
fun testFunction(age: Int, name: String = "", level: Int = 0, class: String = "")

The kotlin bytecode generates:

   @JvmStatic
   @JvmOverloads
   public static final void testFunction(int age, @NotNull String name, int level) {
      testFunction$default(age, name, level, (String)null, 8, (Object)null);
   }

   @JvmStatic
   @JvmOverloads
   public static final void testFunction(int age, @NotNull String name) {
      testFunction$default(age, name, 0, (String)null, 12, (Object)null);
   }

   @JvmStatic
   @JvmOverloads
   public static final void testFunction(int age) {
      testFunction$default(age, (String)null, 0, (String)null, 14, (Object)null);
   }

Which means I can call

testFunction(0)
testFunction(0, "John")
testFunction(0, "John", 1)
testFunction(0, "John", 1, "Warrior")

But I CANNOT call a function like this in java code:

testFunction(0,1)

But in kotlin would be possible! Since name and class have default values.

Could I get some help? How does this work? Am I using it wrong?


Solution

  • You are correct. @JvmOverloads only generates overloads for default parameter values from last to first. Not all possible combinations. It can't do that, because there would be conflicting signatures. For example, if there was a method with only your age parameter and only your level parameter, how would Java know which one to call?

    You can tinker with this by changing the parameter order. So if you need a method with level and age parameters, but no name, you can put those two parameters first in the Kotlin function.