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.
@JvmOverloadsonly 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 yourageparameter and only yourlevelparameter, 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
levelandageparameters, but noname, you can put those two parameters first in the Kotlin function.