Open In App

How to Specify Default Values in Kotlin Functions?

Improve
Improve
Like Article
Like
Save
Share
Report

In Kotlin, you can provide default values to parameters in a function definition. If the function is called with arguments passed, those arguments are used as parameters. However, if the function is called without passing argument(s), default arguments are used. But If you come from the Java world, you might remember that we can’t specify a default value to methods. This means that we can’t do something like this in Java:

public void foo(int a, int b=10) {
}

We need to write two methods for it, and it is known as method overloading:

public void foo(int al {
}

public void foo(int a, int b) {
}

Also, suppose you have a function with three different kinds of parameters, such as these:

public void foo (int a, double b, String c){
}

Then you’ll have seven instances of method overloading:

public void foo (int a, double b, String c),
public void foo (int a, double b) ,
public void foo (double b, String c) ,
public void foo (int a, String c) ,
public void foo (int a) ,
public void foo (double b) ,
public void foo (String c)

Kotlin provides you with default values in the methods by which you can prevent an insane amount of method overloading. Some people might say, “Hey, why don’t we use the builder pattern instead of method overloading?”. Those people are right, but Kotlin’s way is easier than that. Let’s see how!

Example

In Kotlin, parameters of functions can have default values, and they are used when the corresponding argument is omitted. This, in turn, reduces the number of overloads. The preceding example with three different types of parameters can be resolved easily in Kotlin with a lot less code. Let’s add the mentioned code in the editor, run it, and check the output:

Kotlin




fun main (args: Array<String>){
  foo ()
  foo (1)
  foo (1, 0.1)
  foo (1, 0.1, "custom string")
}
  fun foo (a: Int=0, b: Double =0.0, c:String="some default value") {
    printin ("a=$a ,b=$b ,c = Sc")
}


If you run the preceding code, you will see the following output:

Output:

a-0 , b-0.0 ,c - some default value
a=1 , b=0.0 ,c = some default value
a=1 , b=0.1 ,c = some default value
a=1 , b=0.1 ,c = custom string

As you can see, we didn’t have to implement four different methods, and we could map the arguments. The default parameters are used when we don’t call the methods by providing explicit parameters, so when you don’t pass any parameters, it just uses all the default ones. With the help of named arguments, we can decrease the number of methods even further, but we will cover this in the next recipe. One thing to note is that default arguments will also work with constructors. So you can have a class declaration as follows:

data class Event (var eventName: String? - "", var eventSchedule: 
Date? - Date () , var isPrivate: Boolean - false)

Then we can declare objects, as shown:

Event ("Celebration" )
Event ("Celebration", Date () )
Event ("Celebration", Date () , true)

As you can see, with the help of default values in the constructors, we are avoiding the need to implement multiple constructors, which we used to do in Java. Remember that there is a catch here. We won’t be able to do this if you are creating objects in Java. This means that doing things as shown in the following code will not be accepted by Java. Now I know you’ll be like “What happened to 100% interoperability with Java ?!”:

new Event ("Celebration")
new Event ("Celebration", Date () )
new Event ("Celebration", Date () , true)

We just need to do a small modification if we want to expose multiple overloads to Java callers, that is-namely adding @JvmOverloads to the constructors and with default values so that the preceding class declaration becomes this:

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

Also, our method becomes this:

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

This is a small price to pay, but the @JvmOverloads annotation helps our constructors and functions to have default values, called from the Java world too.

If we want our code to work only in the Kotlin world, then we don’t need the @JvmOverloads annotation because Kotlin has its own rules by which it can work with default values in constructors and functions. Adding the @JvmOverloads annotation creates all the necessary overloads. So if you decompile your Kotlin bytecode, you will see all the overloaded versions of constructors and functions.


Last Updated : 11 Oct, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads