Sealed Classes vs Data Classes: Choosing the Best State Option for Your Kotlin Application

Cazimir Roman
4 min readDec 23, 2022
Photo by Diana Light

When developing applications in Kotlin, one of the decisions you may face is how to represent the different states of your application. Two common options for doing this are using sealed classes or data classes. Both of these approaches have their own pros and cons, and the best option for your application will depend on your specific needs and requirements.

A sealed class is a special type of class that can only be subclassed within the same file as the sealed class. This makes it easy to define a fixed set of possible states, as all of the subclasses must be declared in the same file as the sealed class. Sealed classes are often used to represent a finite set of states, such as in a state machine.

sealed class AppState {
object Loading : AppState()
data class Success(val data: Data) : AppState()
data class Error(val message: String) : AppState()
}

In this example, the AppState sealed class has three subclasses: Loading, Success, and Error. These subclasses represent the three possible states of the application: loading, success, and error.

You can use a sealed class like this in your code by using a when expression to handle the different states. For example:

when (appState) {
is AppState.Loading -> showLoadingIndicator()
is AppState.Success -> showData(appState.data)
is AppState.Error -> showError(appState.message)
}

Benefits of sealed classes

One of the main benefits of using sealed classes is that they can help to ensure that your code is correct and easy to understand. Because sealed classes only allow a fixed set of subclasses, you can be sure that any object of a sealed class will be one of the defined subclasses. This makes it easier to reason about your code and can help to reduce the risk of bugs.

Another advantage of sealed classes is that they can make it easier to write code that handles different states in a consistent way. For example, you can use a when expression to handle each of the different states, and the Kotlin compiler will ensure that you have covered all of the possible states. This can make it easier to write correct code and can save you time and effort.

Drawbacks for sealed classes

However, sealed classes also have some drawbacks. One of the main drawbacks is that they can be more verbose than other options, especially if you have a large number of states. Defining a sealed class and all of its subclasses can take more code than using other options, such as data classes or enums.

// Using a sealed class
sealed class AppState {
object Loading : AppState()
data class Success(val data: Data) : AppState()
data class Error(val message: String) : AppState()
}

// Using a data class
data class AppState(val state: String, val data: Data? = null, val message: String? = null)

// Using an enum
enum class AppState {
LOADING,
SUCCESS,
ERROR
}

In contrast, a data class is a simple class that is primarily used to hold data. Data classes are defined using the data keyword and have automatically generated methods for accessing and modifying the data stored in the class. Data classes are often used to hold the state of an object, as they provide a concise and convenient way to represent data.

data class AppState(val state: String, val data: Data? = null, val message: String? = null)

Advantages of data classes

One of the main advantages of data classes is that they are concise and easy to use. Data classes are especially useful when you just need to hold a simple data structure and don’t need any complex logic. They allow you to define the data you need in a single line of code and provide automatically generated methods for accessing and modifying that data.

Another advantage of data classes is that they can be more flexible than sealed classes. Because data classes don’t have any restrictions on where they can be subclassed, you can define them in one file and use them in another without any problems. This can be useful if you need to share data between different parts of your codebase.

Drawbacks for data classes

However, data classes also have some drawbacks. One of the main drawbacks is that they don’t provide the same level of type safety as sealed classes. Because data classes can be subclassed anywhere, it’s possible for other code to define additional subclasses that you aren’t aware of. This can make it harder to reason about your code and can increase the risk of bugs.

In conclusion, sealed classes and data classes are both useful options for representing the different states of your application in Kotlin. Sealed classes are best for situations where you need to define a fixed set of possible states and want to ensure that your code is correct and easy to understand. Data classes are better for situations where you just need to hold simple data and don’t need any complex logic. The best option for your application will depend on your specific needs and requirements.

--

--

Cazimir Roman

A curious developer with a passion for learning and creating innovative solutions to complex problems.