Enum constants have a toString method true False

Frequently, though, we find ourselves needing to model a fixed set of states that has more than two entries. For example, even with something that is nominally a boolean, we might have “true”, “false”, and “undefined”. The latter state would be for cases where we have not yet gone through any code that positively sets the state to “true” or “false”. For example, for some sort of user preference, perhaps the user has not visited the “settings” screen to state their preference just yet, so their preference is “undefined”.

The more you look, the more you find things that might be modeled this way:

  • The error responses from a server API
  • The steps in a wizard-style “signup” set of screens
  • The modes of transportation that a
    enum class HungerState {
      NOT_HUNGRY,
      SOMETIMES_HUNGRY,
      ME_ALWAYS_HUNGRY,
      RAVENOUS,
      YOU_LOOK_LIKE_FOOD
    }
    
    2 object might be taking (walking? biking? driving? flying? skiing? jet-skiing?)
  • And so on

For these cases, Kotlin offers two programming constructs: enumerations (“enums”) and sealed classes. In this chapter, we will explore each of these.

Some programming languages — particularly those that grew out of C — offer “enums” as first-class constructs. So, Java has an

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3:

enum ServerError {
  INVALID_INPUT,
  OUT_OF_STORAGE_SPACE,
  USER_NOT_FOUND,
  CLIENT_NOT_FOUND,
  SERVER_NOT_FOUND,
  WHOEVER_YOU_THINK_YOU_ARE_TALKING_TO_NOT_FOUND
}

Kotlin’s

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 option resembles that of Java.

Basic Syntax and Usage

The first difference between Kotlin and Java is in the declaration. In Java,

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 exists as a standalone keyword. In Kotlin, the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 decorates
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
7, much like how
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
8 is a type of class:

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

You can then refer to

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 values using standard dot notation, such as
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}
0.

Since this is a type of class, you use an

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 in Kotlin the same way that you would any other class, such as in a constructor parameter:

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}

Class Features

Since a Kotlin

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 is a class, you can use many class features in an
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3.

Constructors

The most commonly seen of these is the constructor, used to provide values to define an individual

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 constant:

enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}

Here, we use a constructor to associate a

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}
5 value with each
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}
6 constant. This is just an ordinary class property, so you can ask a constant like
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}
7 for its
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}
5.

Functions

An

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class can implement functions, including overriding base ones like
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0:

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}

The list of constants must be the first thing in the

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 declaration — if we tried to have our
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0 before the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}

data class Animal(
  val species: String,
  val ageInYears: Float,
  val hungry: HungerState = HungerState.SOMETIMES_HUNGRY
) {
  var isFriendly = true
  val isCommonlySeenFlyingInTornadoes = false
}
7, we would fail with a compile error.

Note that in this case the comma-delimited list of constants is ended with a semicolon. If the only thing in the

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 declaration is the list of constants, the overall closing brace of the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 is sufficient to end the list of constants. If you have other things after the constants, though, such as our
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0 function, you need the semicolon to officially end the list of constants.

An

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class is intrinsically
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
8, so you can define abstract functions as well, implementing them on individual constants:

enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}

Here, each

enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
9 knows the next
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
9 in the sequence, by overriding an abstract
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}
1 function declared for
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
9. This gets a bit odd with the last step, as by definition the last step is last, so there is no “next step”. You might be tempted to return something like
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}
3 from
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}
1 on
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}
5… we will see how that works in an upcoming chapter.

Limitations

An

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class is allowed to implement interfaces, but it is not allowed to extend another class.

Also, akin to

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
8 classes, an
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 cannot be
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}
9 for extension… by classes outside of the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class. Each of the enumerated constants (e.g.,
enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
1,
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
}
5 in the above example) is in effect a subclass of the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class, complete with
enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
4 methods to match the
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
8 ones in the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class. But you cannot create new constants from outside the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class, and you cannot create arbitrary other subclasses of the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class.

Common Properties

Each enumerated constant has two properties, beyond those that you might declare yourself:

enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
9 and
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}
0.
enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
9 returns the symbolic name that you gave the constant in your code, and
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}
0 returns the 0-based index indicating where this constant appears in the list of constants. You can access
enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
9 and
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}
0 as you can any other property:

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}

This yields:

WTF?
501
INTERNAL_SERVER_ERROR
5

The name could be useful in

enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0 implementations and similar scenarios. The ordinal is less likely to be useful — in particular, since it is position-dependent, it may be a bit fragile, as somebody reordering lines of your code might change the ordinal values for those constants.

Conversion

Each

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class is given a few functions to be called on the class itself. One is
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}
7. This returns a constant given the symbolic name that you gave the constant in your code. In other words, it works like the inverse of the
enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
9 property —
enum class WizardStep {
  INTRO {
    override fun nextStep() = REGISTER
  },
  REGISTER {
    override fun nextStep() = PERMISSIONS
  },
  PERMISSIONS {
    override fun nextStep() = THANKS
  },
  THANKS {
    override fun nextStep() = THANKS
  };

  abstract fun nextStep(): WizardStep
}
9 gives you the symbolic name for a constant, while
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}
7 gives you the constant for a symbolic name:

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}

This results in:

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.INTERNAL_SERVER_ERROR.toString())
  println(HttpResponse.INTERNAL_SERVER_ERROR.code)
  println(HttpResponse.INTERNAL_SERVER_ERROR.name)
  println(HttpResponse.INTERNAL_SERVER_ERROR.ordinal)
}
7 returns the
WTF?
501
INTERNAL_SERVER_ERROR
5
2 constant.
WTF?
501
INTERNAL_SERVER_ERROR
5
3 then calls
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0 implicitly on that constant, and our overridden
enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0 function returns
WTF?
501
INTERNAL_SERVER_ERROR
5
6.

Iteration

Also, you can call

WTF?
501
INTERNAL_SERVER_ERROR
5
7 on the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class itself (e.g.,
WTF?
501
INTERNAL_SERVER_ERROR
5
9). This will allow you to iterate over all of the constant members of the
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class, in the order in which they were declared. Hence, this code:

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  for (constant in HttpResponse.values()) {
    println(constant)
  }
}

results in:

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
0

Exhaustive enum class HttpResponse(val code: Int, val message: String) { OK(200, "OK"), MOVED_PERMANENTLY(301, "Moved Permanently"), NOT_MODIFIED(304, "Not Modified"), UNAUTHORIZED(401, "Unauthorized"), NOT_FOUND(404, "Not Found"), INTERNAL_SERVER_ERROR(501, "WTF?"); override fun toString() = message } fun main() { println(HttpResponse.valueOf("NOT_MODIFIED")) }1

We saw that you can use

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1 as an expression, where each one of the branches inside the
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1 supply the value for the expression when that branch is
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
4. However, one limitation that we saw was that you needed an
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
5 condition when using
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1 as an expression, as for any possible condition, the
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1 needs to generate a value.

One exception to that rule is an “exhaustive

enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1” based on an
enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 class. If you have conditions for each enumerated constant, you do not need an
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
5 condition, since by definition every possibility will have been handled by one of the other conditions.

For example, this script yields the same result as the one shown above:

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
1

This time,

enum class HttpResponse(val code: Int) {
  OK(200),
  MOVED_PERMANENTLY(301),
  NOT_MODIFIED(304),
  UNAUTHORIZED(401),
  NOT_FOUND(404),
  INTERNAL_SERVER_ERROR(501)
}

fun main() {
  println(HttpResponse.OK.code)
}
0 no longer just reads some property. We no longer have those properties, and instead use a
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1 expression to get the human-readable message to go along with the HTTP response code. We do not need an
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
5 in the
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1, since every possible enumerated constant has its own condition. We have “exhausted” all possibilities with the specific conditions, and so this is an “exhaustive”
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
1.

This particular example is really silly — having these messages as properties would be a better choice. However, you may have other places in your code where you need to branch based on an

enum class HungerState {
  NOT_HUNGRY,
  SOMETIMES_HUNGRY,
  ME_ALWAYS_HUNGRY,
  RAVENOUS,
  YOU_LOOK_LIKE_FOOD
}
3 value, and so long as all possible values are accounted for, you do not need an
enum class HttpResponse(val code: Int, val message: String) {
  OK(200, "OK"),
  MOVED_PERMANENTLY(301, "Moved Permanently"),
  NOT_MODIFIED(304, "Not Modified"),
  UNAUTHORIZED(401, "Unauthorized"),
  NOT_FOUND(404, "Not Found"),
  INTERNAL_SERVER_ERROR(501, "WTF?");

  override fun toString() = message
}

fun main() {
  println(HttpResponse.valueOf("NOT_MODIFIED"))
}
5.

Can you declare an enumerated data type inside a method?

T/F: You can declare an enumerated data type inside a method. False, enumerated data type declared inside a class not inside a method.

Which of the following is not true about a static method?

Which of the following is NOT true about static methods? They are created by placing the key word static after the access specifier in the method header.

Which of the following can you use to compare two enum data values?

equals method uses == operator internally to check if two enum are equal. This means, You can compare Enum using both == and equals method.

When you write an enumerated type declaration you are actually creating a special kind of?

An enumerated data type is actually a special type of class. An instance of a class does not have to exist in order for values to be stored in a class's static fields.