If you are coming from Java world, you might already have heard about the method overloading in Java. Kotlin, with the help of default parameters and named arguments helps us to reduce the number of overloads that we generally need in Java world.

That means, in Kotlin, you can define a method like

fun bar(a:Int=0, b: Double =0.0, c:String="default value"){

println("a=$a , b=$b ,c = $c")

}

And then call it like

bar(1)

The output would be like:

a=1, b=0.0, c=default value

Not only this, you can call that with varying overloads, like:

bar()

bar(1)

bar(1,0.1)

bar(1,0.1,"Custom string")

All with just one declaration of method. Notice in Java you needed to overload 4 methods in order to call them like above.

The default values work with constructors also, so you can have a class like:

data class Event(var name: String? = "", var date: Date? = Date(), var isPrivate: Boolean = false)

And then you can create objects like

Event(“Celebration”,Date(),true) Event(“Birthday party”)

Remember that we needed to have multiple constructors in Java to pull off the above thing.

BUT, there is a catch here. If you call them(functions or constructor with default values) from Kotlin, they will work fine. But if you try to do it from Java, they will not work. That basically means, that you cannot do this in Java:

new Event(“Birthday party”); new Event(“Celebration”,new Date(),true);

Now you’ll be like “Hey! what happened to 100% interoperability?” Fret not, with a slight modification, we can make it work with Java code too.

We just need to add @JvmOverloads annotation to functions and constructors with default values. So they would look like:

@JvmOverloads fun bar(a:Int=0, b: Double =0.0, c:String="default value"){

println("a=$a , b=$b ,c = $c")

}

data class Event @JvmOverloads constructor (var name: String? = "", var date: Date? = Date(), var isPrivate: Boolean = false)

Notice that we now need to add constructor keyword after annotation(rule in Kotlin). The reason to add that notation is that Kotlin, internally has rules setup to understand whats going in with default values, but Java doesn’t. So adding @JvmOverloads forces it generate multiple overloads for that function or constructors. If you decompile the code and look into that Java file, you will find multiple overloads of them. Something like:

@JvmOverloads

public Event(@Nullable String name, @Nullable Date date) {

this(eventName, date, false, 4, (DefaultConstructorMarker)null);

}



@JvmOverloads

public Event(@Nullable String name) {

this(eventName, (Date)null, false, 6, (DefaultConstructorMarker)null);

}



@JvmOverloads

public Event() {

this((String)null, (Date)null, false, 7, (DefaultConstructorMarker)null);

}

And similarly for method:

@JvmOverloads

public static final void foo(int a, double b) {

foo$default(a, b, (String)null, 4, (Object)null);

}



@JvmOverloads

public static final void foo(int a) {

foo$default(a, 0.0D, (String)null, 6, (Object)null);

}



@JvmOverloads

public static final void foo() {

foo$default(0, 0.0D, (String)null, 7, (Object)null);

}



PS: I’ve made this simple free Android app that helps you maintain consistency toward your goals, based on the technologies/tools mentioned above. Feel free to check it out:

Please clap, if you enjoyed the article.