1. Overview
In this tutorial, we’ll show how to create a class instance with optional fields. First, we’ll show how to do it with a primary constructor with default values set to null. Additionally, we’ll show how to use a secondary constructor with default values.
2. Initialize Values With Null
In Kotlin, a data class represents a data container object. By default, it exposes a primary constructor, which requires all fields to be provided. Let’s create an example:
class DataClassWithMandatoryFields(
val name: String,
val surname: String,
val age: Number
)
Now, the instance creation looks like:
val objectWithAllValuesProvided = DataClassWithMandatoryFields("John", "Deere", 82)
By default, in the data class, all fields are mandatory in the primary constructor. In case we don’t provide a value for any fields, the compiler throws an exception: “No value passed for parameter ‘
Let’s write a new data class where the fields aren’t mandatory. We’ll modify the constructor and initialize all values with null:
class DataClassWithNullInitializedFields(
val name: String? = null,
val surname: String? = null,
val age: Number? = null
)
Now, we can create an instance with no value provided. Additionally, we can provide selected values:
val objectWithNullInitializedFields = DataClassWithNullInitializedFields()
val objectWithNameInitializedFields = DataClassWithNullInitializedFields(name = "John")
However, such an approach means that we must check nullability before we access the field’s properties:
assertThat(objectWithNameInitializedFields.name?.length).isEqualTo("4")
3. Set Default Values in Primary Constructor
After that, let’s improve the previous version and eliminate nullability. For all constructor parameters, we set a default value:
class DataClassWithDefaultValues(
val name: String = "",
val surname: String = "",
val age: Number = Int.MIN_VALUE
)
Thanks to that, we avoid the need for “safe calls” to handle null values. Similarly, we can create an object with some fields provided as in the previous example:
val dataClassWithDefaultValues = DataClassWithDefaultValues()
val dataClassWithNameProvided = DataClassWithDefaultValues(name = "John")
And now, we don’t have to check the nullability of the object’s fields:
assertThat(dataClassWithNameProvided.name.length).isEqualTo(4)
4. Secondary Constructor With Default Values
Now, let’s modify the approach with default values. Instead of default values in the primary constructor, we create secondary constructors:
class DataClassWithSecondaryConstructors(
val name: String,
val surname: String,
val age: Number
) {
constructor() : this("", "Doe", Int.MIN_VALUE)
constructor(name: String) : this(name, "Deere", Int.MIN_VALUE)
constructor(name: String, surname: String) : this(name, surname, Int.MIN_VALUE)
}
The construction of an object looks the same as in the previous example:
val dataClassWithSecondaryConstructors = DataClassWithSecondaryConstructors()
val objectWithNameSet = DataClassWithSecondaryConstructors(name = "John" )
As a result, we can set different defaults depending on the constructor. In our example, when no value is provided, we set the surname value to “Doe”. In case only the name is provided, we set the surname to “Deere”:
assertThat(objectWithNameSet.surname).isEqualTo("Deere")
5. Conclusion
In this short article, we showed how to create a class instance with optional fields. First, we showed how to do it with a primary constructor. After that, we showed how to use a secondary constructor with default values.
As always, the source code of the examples is available over on GitHub.