In this tutorial, we’ll be looking into Kotlin Enum classes. What’s in store for them? How are they different from enums in Java? We’ll be discussing everything you need to know about kotlin enum class at length.
Table of Contents
Kotlin Enum Class
Enumerations in Kotlin are data types that hold a set of constants. Enums are defined by adding the modifier enum
in front of a class as shown below. Yes, in Kotlin, Enums are classes.
enum class Months{
January,
February,
March
}
Here are some important points about enum classes in kotlin.
- Each enum constant is an object. Enum constants are separated by commas.
- Each of the enum constants acts as separate instances of the class.
- Enums are useful in enhancing the readability of your code since it assigns pre-defined names to constants.
- Unlike classes, an instance of enum classes cannot be created using constructors.
- Hence, we can assert that enum classes are abstract.
Let’s see how the enum class is initialized in the main
function of our class.
fun main(args: Array<String>) {
println(Months.January) //prints January
println(Months.values().size) //prints 3
println(Months.valueOf("March")) //prints March
for (enum in Months.values()) {
println(enum.name)
}
println(Months.valueOf("Mar")) //throws java.lang.IllegalArgumentException: No enum constant Months.Mar
}
Few inferences from the above code:
values()
returns the enum constants in the form of an array over which we can iterate to retrieve each enum constant.valueOf()
is used to fetch an enum constant using a String as the argument.- If the value doesn’t match with any of the constants, a runtime exception would be thrown.
Let’s see how to tackle this scenario.
fun enumContains(name: String): Boolean {
return enumValues<Months>().any { it.name == name }
}
fun main(args: Array<String>) {
if (enumContains("")) {
println(Months.valueOf(""))
} else {
println("The string value does not match with any of the enum constants.") //this gets printed.
}
}
enumContains
is a function that calls the lambda function any which iterates over the enum constants to check if any of them matches the string and returns a boolean.
Enum Properties
Every enum constant has properties: name
, ordinal
to retrieve the name and position of the constant.
fun main(args: Array<String>) {
println(Months.January.name) //prints January
println(Months.March.ordinal) // prints 2
for (enum in Months.values()) {
println(enum.name)
}
}
Enum toString()
We can override the toString() function in the enum class as shown below.
enum class Months {
January,
February,
March;
override fun toString(): String {
return super.toString().toUpperCase()
}
}
fun main(args: Array<String>) {
println(Months.January) //prints JANUARY
println(Months.January.name) //prints January
println(Months.valueOf("March")) //prints MARCH
}
Enums are classes. So besides defining the constants we can define other things as well that can be present in a class. To do so we need to first end the enum part with a semi colon.
Note: Month.January
invokes the toString()
method of the class whereas Month.January.name
directly prints the enum constant’s name.
Enum Initialisation
Enum constants can be initialized using primary constructors as shown below.
enum class Months(var shorthand: String) {
January("JAN"),
February("FEB"),
March("MAR");
}
fun main(args: Array<String>) {
var x = Months.January
println(x.shorthand) //prints JAN
x.shorthand = "Shorthand changed to J."
println(Months.January.shorthand) //prints Shorthand changed to J.
}
Enums as Anonymous classes
Enum constants can behave as anonymous classes be implementing their own functions along with overriding base functions from the class as shown below.
enum class Months(var shorthand: String) {
January("JAN"){
override fun printSomething() {
println("First month of the year.")
}
},
February("FEB"){
override fun printSomething() {
println("Second month of the year.")
}
},
March("MAR"){
override fun printSomething() {
println("Third month of the year.")
}
};
var a: String = "Hello, Kotlin Enums"
abstract fun printSomething()
}
fun main(args: Array<String>) {
Months.February.printSomething() //prints Second month of the year.
println(Months.February.a) //prints Hello, Kotlin Enums
}
Each of the enum constants must override
Enum inside an Enum
It’s possible to define another enum class in the current enum class as shown below.
enum class Months {
January,
February,
March;
enum class Day{
Monday,
Tuesday,
Wednesday
}
}
fun main(args: Array<String>) {
println(Months.Day.Tuesday) //prints Tuesday
}
Only an enum class can invoke another one. The inner class Day
cannot be invoked from the enum constants.
Enums and when
when
is Kotlin equivalent of switch in Java. We’ve covered the workings of it in the Control Flow tutorial.
An example showing how when statements are used with enums is given below.
enum class Months {
January,
February,
March;
}
fun main(args: Array<String>) {
var m = Months.February
when (m) {
Months.January -> print("Matches with Jan")
Months.February -> print("Matches with Feb") //prints this.
Months.March -> print("Matches with Mar")
}
}
This brings an end to kotlin enum tutorial.
References: Kotlin Docs
To the point and informative
Concise and very very helpful
Hey, thanks for the helpful overview. There’s two quick errors I’d recommend fixing. In the second block of code you have
println(Months.valueOf(“Mar”)) //prints March
However wouldn’t this not “print Match”, but throw an error? Because valueOf has to be an exact string match? The other error is in “Enums as Anonymous classes” in code block seven
println(Months.February.string) //prints Hello, Kotlin Enums
should be
println(Months.February.a) //prints Hello, Kotlin Enums
Thanks for observing that. Fixed those glitches.