言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Kotlin辞典

  1. トップページ
  2. Kotlin辞典
  3. enum class

enum class

対応: Kotlin 1.0(2016)

『enum class』は決まった値の集合を型として定義する列挙型です。『values()』『valueOf()』などで列挙子の一覧や取得が行えます。

構文

// 基本的な enum class
enum class 列挙型名 {
    定数1, 定数2, 定数3
}

// プロパティを持つ enum class
enum class 列挙型名(val プロパティ名: 型) {
    定数1(値), 定数2(値)
}

構文一覧

構文 / プロパティ概要
列挙型名.values()すべての列挙子を配列で返します。
列挙型名.valueOf("名前")名前に一致する列挙子を返します。存在しない場合は例外が発生します。
列挙子.ordinal列挙子の宣言順インデックス(0始まり)を返します。
列挙子.name列挙子の名前を文字列で返します。
enumValues<T>()型パラメーターで列挙子の配列を取得します。
enumValueOf<T>("名前")型パラメーターで名前から列挙子を取得します。

サンプルコード

enum_class.kt
// 曜日を表す enum class
enum class DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN
}

// プロパティを持つ enum class
enum class Color(val code: String) {
    RED("#FF0000"),
    GREEN("#00FF00"),
    BLUE("#0000FF")
}

fun main() {
    // name と ordinal を確認する
    val day = DayOfWeek.WED
    println(day.name) // WED
    println(day.ordinal) // 2

    // values() でループ処理する
    for (d in DayOfWeek.values()) {
        println("${d.ordinal}: ${d.name}")
    }

    // valueOf() で名前から列挙子を取得する
    val c = Color.valueOf("BLUE")
    println(c.code) // #0000FF

    // when 式と組み合わせると便利
    val msg = when (day) {
        DayOfWeek.SAT, DayOfWeek.SUN -> "休日"
        else -> "平日"
    }
    println(msg) // 平日
}

コンパイルして実行すると次のようになります。

kotlinc enum_class.kt -include-runtime -d enum_class.jar
java -jar enum_class.jar
WED
2
0: MON
1: TUE
2: WED
3: THU
4: FRI
5: SAT
6: SUN
#0000FF
平日

よくあるミス

よくあるミス1: 『valueOf()』に存在しない名前を渡すと『IllegalArgumentException』が発生する。

NG例1 — valueOf() に存在しない名前を渡す
enum class Rank { BRONZE, SILVER, GOLD }

fun main() {
    val r = Rank.valueOf("PLATINUM") // IllegalArgumentException
    println(r)
}
enum_class_ok1.kt
enum class Rank { BRONZE, SILVER, GOLD }

fun main() {
    val r = enumValues<Rank>().firstOrNull { it.name == "PLATINUM" }
    println(r) // null
}

コンパイルして実行すると次のようになります。

kotlinc enum_class_ok1.kt -include-runtime -d enum_class_ok1.jar
java -jar enum_class_ok1.jar
null

よくあるミス2: 『ordinal』の数値に依存したコードを書くと、宣言順を変えたときに壊れる。

NG例2 — ordinal の数値をハードコードする
enum class Priority { LOW, MEDIUM, HIGH }

fun main() {
    if (Priority.HIGH.ordinal == 2) println("HIGH は3番目")
    // 宣言順を変えると ordinal の値が変わる
}
enum_class_ok2.kt
enum class Priority(val level: Int) { LOW(1), MEDIUM(5), HIGH(10) }

fun main() {
    val p = Priority.HIGH
    println(p.level) // 10(宣言順に依存しない)
    println(p.name) // HIGH
}

コンパイルして実行すると次のようになります。

kotlinc enum_class_ok2.kt -include-runtime -d enum_class_ok2.jar
java -jar enum_class_ok2.jar
10
HIGH

よくあるミス3: 『when』式で全列挙子を網羅せずに『else』を使うと、新しい列挙子を追加したときに見落としが起きる。

NG例3 — when に else を書いて網羅性を失う
enum class Color { RED, GREEN, BLUE }

fun describe(c: Color): String = when (c) {
    Color.RED -> "赤"
    else -> "その他" // GREEN/BLUE の分岐が抜けていても気づけない
}
enum_class_ok3.kt
enum class Color { RED, GREEN, BLUE }

fun describe(c: Color): String = when (c) {
    Color.RED   -> "赤"
    Color.GREEN -> "緑"
    Color.BLUE  -> "青"
    // 全列挙子を網羅すれば else 不要。新しい列挙子を追加するとコンパイルエラーになる
}

fun main() {
    println(describe(Color.BLUE)) // 青
}

コンパイルして実行すると次のようになります。

kotlinc enum_class_ok3.kt -include-runtime -d enum_class_ok3.jar
java -jar enum_class_ok3.jar
青

概要

『enum class』は定数の集合を型安全に扱うための仕組みです。すべての列挙子は自動的に『name』(宣言名の文字列)と『ordinal』(0始まりのインデックス)を持ちます。

コンストラクタにプロパティを定義すると、各列挙子に異なる値を持たせることができます。『valueOf()』に存在しない名前を渡すと『IllegalArgumentException』が発生するため、不明な文字列を変換する場合は『try-catch』や『enumValues()』でのフィルタリングを検討してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。