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?
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.