Great question @DeveScie
The reason it failed is because the doSomething() without any parameter function does not exists in byte code level. To understand, you need to see how your kotlin code is converted into Java byte code.
Here is your class's Java representation (some unrelated code is omitted)
public final class MyViewModel {
public final void doSomething(@NotNull String myVar) {
Intrinsics.checkParameterIsNotNull(myVar, "myVar");
}
// $FF: synthetic method
public static void doSomething$default(MyViewModel var0, String var1, int var2, Object var3) {
if ((var2 & 1) != 0) {
var1 = "defValue";
}
var0.doSomething(var1);
}
}
And here is a Kotlin test class that uses this function
class TestClass {
fun testFunction() {
val vm = MyViewModel()
vm.doSomething()
vm.doSomething("Value")
}
}
Which results in Java code below
public final class TestClass {
public final void testFunction() {
MyViewModel vm = new MyViewModel();
MyViewModel.doSomething$default(vm, (String)null, 1, (Object)null);
vm.doSomething("Value");
}
}
As you can see, the default value you have in kotlin is actually called by:
MyViewModel.doSomething$default(vm, (String)null, 1, (Object)null);
So, you should have a separate method for other case. Hope it helps.
UPDATE: Based on @Uli's answer below, another solution is to add @JvmOverloads to your kotlin function.
class MyViewModel {
@JvmOverloads
fun doSomething(myVar: String = "defValue") {
}
}
Now becomes following in Java
public final class MyViewModel {
@JvmOverloads
public final void doSomething() {
doSomething$default(this, (String) null, 1, (Object) null);
}
@JvmOverloads
public final void doSomething(@NotNull String myVar) {
Intrinsics.checkParameterIsNotNull(myVar, "myVar");
}
// $FF: synthetic method
public static void doSomething$default(MyViewModel var0, String var1, int var2, Object var3) {
if ((var2 & 1) != 0) {
var1 = "defValue";
}
var0.doSomething(var1);
}
}
Thanks Uli for reminding me about this option.