enum
- 열거형; enumeration
- 여러 개의 이름이 붙은 상수를 하나의 타입으로 묶어서 표현
- 상수 값이 미리 정해져있고, 컴파일 시점에 확정
일반 enum
- 상수 목록만 정의: 추가 메서드나 프로퍼티 없음
- 각 상수는 고유한 값을 가짐
- 보통 switch-case나 조건문에서 사용
Java에서의 enum
public enum Direction {
NORTH,
SOUTH,
EAST,
WEST
}
class Main {
public static void main(String[] args) {
Direction dir = Direction.NORTH;
System.out.println(dir); // NORTH
}
}
- Direction 타입의 변수는 4개의 값 중 하나만 가짐
enum vs. 상수(final static)
// 기존 상수 정의 방식
public static final int NORTH = 0;
public static final int SOUTH = 1;
// enum 방식
enum Direction { NORTH, SOUTH }
- final static: 타입 구분이 불가능
- enum: 타입 강제 → 타입 안정성
Kotlin에서의 enum
- enum class로 열거형을 생성
- Java처럼 enum과 enum class를 구분하지 않음 → 모든 열거형이 사실상 클래스
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
- Direction은 열거형이자 클래스로 생성자/메서드/프로퍼티도 가질 수 있음.
enum Class
- 열거형 클래스; enumeration class
- 상수 집합을 정의 할 때 사용
- 각 상수는 해당 enum class 타입의 고유한 인스턴스
- 상수명은 관례적으로 대문자로 표기
- Kotlin에서는 모든 열거형이 enum class로 정의
기본 선언
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
fun main() {
val dir = Direction.NORTH
println(dir) // NORTH
println(dir.name) // "NORTH"
println(dir.ordinal) // 0
}
- name → 상수이름(String)
- ordinal → 상수의 순서 (0부터 시작)
생성자 & 프로퍼티
- enum은 생성자와 프로퍼티 소유 가능
enum class Day(val isWeekend: Boolean) {
MONDAY(false),
TUESDAY(false),
WEDNESDAY(false),
THURSDAY(false),
FRIDAY(false),
SATURDAY(true),
SUNDAY(true)
}
fun main() {
println(Day.SATURDAY.isWeekend) // true
}
메서드 포함
- enum class 안에 메서드 정의 가능
- 각 상수는 추상 메서드 구현 가능
enum class Operation {
PLUS {
override fun apply(a: Int, b: Int) = a + b
},
MINUS {
override fun apply(a: Int, b: Int) = a - b
};
abstract fun apply(a: Int, b: Int): Int
}
fun main() {
println(Operation.PLUS.apply(3, 4)) // 7
}
values() & valueOf()
- Java 스타일의 정적메서드
- enum 클래스 이름 뒤에 바로 호출
- 컴파일 타임에 enum 클래스가 생성하는 메서드
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
fun main() {
val dirs = Direction.values()
println(dirs.joinToString()) // NORTH, SOUTH, EAST, WEST
val east = Direction.valueOf("EAST")
println(east) // EAST
}
- values(): 모든 enum 상수를 배열로 반환
- valueOf(”이름”): 해당 이름의 상수 반환
enumValues<T>() & enumValueOf<T>(name: String)
- 제네릭 함수로 클래스 이름을 직접 쓰지 않고 사용 가능
- T가 컴파일 시점에 enum 클래스여야한다는 제약이 있음
- Kotlin의 리플렉션과 제네릭 기능 활용 가능
enum class Color { RED, GREEN, BLUE }
fun main() {
val colors = enumValues<Color>()
println(colors.joinToString()) // [RED, GREEN, BLUE]
val red = enumValueOf<Color>("RED")
println(red) // Color.RED
}
- enumValues<T>() : 모든 상수 배열 반환
- enumValueOf<T>(name: String) : 이름으로 상수 찾기
values(), valueOf(String), enumValues<T>(), enumValueOf<T>() 차이점
구분 | 호출 방식 | 특징 | 사용 위치 |
values() | EnumClass.values() | enum 클래스의 static 메서드 | Java 스타일, 컴파일러 자동 생성 |
valueOf(String) | EnumClass.valueOf("NAME") | static 메서드, 이름으로 반환 | Java 스타일 |
enumValues<T>() | enumValues<EnumType>() | 제네릭 함수, 타입 인자로 사용 | Kotlin 표준 라이브러리 |
enumValueOf<T>() | enumValueOf<EnumType>("NAME") | 제네릭 함수, 이름으로 반환 | Kotlin 표준 라이브러리 |
when 표현식 사용
- when에서 enum을 사용 시 모든 값을 처리하면 else 사용 불필요
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
fun describe(dir: Direction) = when (dir) {
Direction.NORTH -> "위쪽"
Direction.SOUTH -> "아래쪽"
Direction.EAST -> "오른쪽"
Direction.WEST -> "왼쪽"
}
fun main() {
val dir = Direction.NORTH
println(describe(dir)) // 위쪽
}
enum calss vs. seald class
특징 | enum class | seald class |
상수 개수 | 고정 (컴파일 시) | 확장 가능(같은 파일) |
인스턴스 | 미리 정의된 상수 | 각 하위 클래스가 별도 인스턴스 |
생성자 | 가질 수 있음 | 가질 수 있음 |
사용 예 | 방향, 요일, 상태값 | 상태 표현, 복합 데이터 타입 |
실습 문제
1. Enum↔String
Season enum을 보고 아래 조건에 맞추어 문제를 푸시오.
- fromDisplayName 함수를 구현하여, 한글 표시 이름으로부터 Season을 찾아 반환하시오.
- 없는 이름이 들어오면 null을 반환하시오.
enum class Season(val displayName: String) {
SPRING("봄"),
SUMMER("여름"),
AUTUMN("가을"),
WINTER("겨울");
companion object {
// TODO: fromDisplayName 구현
}
}
fun main() {
println(Season.fromDisplayName("봄")) // SPRING
println(Season.fromDisplayName("가을")) // AUTUMN
println(Season.fromDisplayName("장마")) // null
}
[힌트] enumValues<Season>() + find를 사용
답:
enum class Season(val displayName: String) {
SPRING("봄"),
SUMMER("여름"),
AUTUMN("가을"),
WINTER("겨울");
companion object {
fun fromDisplayName(name: String): Season? {
return enumValues<Season>().find { it.displayName == name }
}
}
}
fun main() {
println(Season.fromDisplayName("봄")) // SPRING
println(Season.fromDisplayName("가을")) // AUTUMN
println(Season.fromDisplayName("장마")) // null
}
2. enum에 로직 포함하기
Operation enum은 두 숫자를 계산하는 기능을 수행해야한다.
각 상수에 대한 apply 메서드를 구현하시오.
enum class Operation {
PLUS, MINUS, TIMES, DIVIDE;
abstract fun apply(a: Int, b: Int): Int
}
fun main() {
println(Operation.PLUS.apply(3, 5)) // 8
println(Operation.DIVIDE.apply(10, 2)) // 5
}
[힌트] enum의 각 상수에 대해 익명 클래스처럼 오버라이드 가능
답:
enum class Operation {
PLUS {
override fun apply(a: Int, b: Int) = a + b
},
MINUS {
override fun apply(a: Int, b: Int) = a - b
},
TIMES {
override fun apply(a: Int, b: Int) = a * b
},
DIVIDE {
override fun apply(a: Int, b: Int) = a / b
};
abstract fun apply(a: Int, b: Int): Int
}
fun main() {
println(Operation.PLUS.apply(3, 5)) // 8
println(Operation.DIVIDE.apply(10, 2)) // 5
}
3. Gson과 enum 변환
Status enum을 포함하는 데이터 클래스이다.
JSON으로 객체를 변환할 때 Status가 올바르게 매핑되도록 구현하시오.
import com.google.gson.Gson
enum class Status {
ACTIVE, INACTIVE
}
data class User(val name: String, val status: Status)
fun main() {
val json = """{"name":"홍길동","status":"ACTIVE"}"""
// TODO: Gson으로 User 객체로 변환
}
[힌트] Gson이 기본적으로 enum 이름과 문자열 매핑 지원
답:
import com.google.gson.Gson
enum class Status {
ACTIVE, INACTIVE
}
data class User(val name: String, val status: Status)
fun main() {
val json = """{"name":"홍길동","status":"ACTIVE"}"""
val user = Gson().fromJson(json, User::class.java)
println(user) // User(name=홍길동, status=ACTIVE)
}
'개발새발 > 코틀린' 카테고리의 다른 글
[코틀린/Kotlin] SAM - Java 표준 API (1) | 2025.09.12 |
---|---|
[코틀린/Kotlin] SAM; Single Abstract Method (0) | 2025.09.10 |
[코틀린/Kotlin] qualifiedName (0) | 2025.09.06 |
[코틀린/Kotlin] 로컬 클래스(Local Class) (1) | 2025.09.05 |
[코틀린/Kotlin] 익명 클래스(Anonymous Class) (0) | 2025.09.04 |