[WHITESHIP #1] 11. Enum
#Season1 백기선님과 함께하는 자바 온라인 스터디
목표
자바의 열거형에 대해 학습하세요.
학습 내용
-
enum 정의하는 방법
-
enum이 제공하는 메소드 (values()와 valueOf())
-
java.lang.Enum
-
EnumSet
enum
관련 상수를 모아 사용할 수 있는 상수들의 그룹을 표현할 수 있다.
java 에서는 JDK 1.5 이상부터 지원하며, C/C++과는 다르게 변수, 메소드 그리고 생성자를 추가할 수 있다.
enum 정의하는 방법
아래와 같이 Role을 정의하고, 다음과 같이 사용할 수 있다.
Java Naming Convention에 따르면, 대문자 및 상수로 정의하는 것을 권장한다. 9 - Naming Conventions
public enum Role {
ADMIN, GENERAL
}
public class EnumMain {
public static void main(String[] args) {
Role role = Role.ADMIN;
System.out.println(role); // java.lang.Enum에서 toString() 메서드가 오버라이드 되어짐
}
}
enum의 특징
- enum 자체는 클래스이며, 인스턴스 통제된다. (Factory Method & Singleton을 이용해 인스턴스가 하나만 만들어짐을 보장한다.)
- enum은 java.lang.Enum 클래스에 의해 상속된다. (타 클래스를 상속할 수 없다.)
- toString() 메소드는 java.lang.Enum 클래스에서 오버라이드 되어진다.
- 지원 메소드에는 java.lang.Enum 클래스의 static 메소드인 values(), valueof() 와, static 메소드가 아닌, name(), ordinal(), compareTo(), equals() 를 지원한다.
enum이 제공하는 메소드
1. values()
enum에 정의된 열거타입을 배열로 반환해 준다.
@Test
void printValues() {
Role[] values = Role.values();
Stream.of(values)
.forEach(System.out::println);
}
ADMIN
GENERAL
2. valueOf()
enum에서 이름을 매개변수로 받고, 열거 타입을 반환한다. 또한 정의되어 있는 열거 타입을 찾을 수 없다면, IllegalArgumentException을 반환한다.
Role.valueOf(“ADMIN”) 은 Role.ADMIN과 같다.
@Test
void isEqualValueOf() {
assertEquals(Role.valueOf("ADMIN"), Role.ADMIN);
assertThrows(IllegalArgumentException.class, () -> Role.valueOf("EMPTY"));
}
3. name()
enum에 정의된 열거 타입 이름을 반환해준다.
@Test
void isEqualNameString() {
Role adminRole = Role.ADMIN;
String name = adminRole.name();
assertEquals(name, "ADMIN");
}
4. ordinal()
enum에 정의된 열거 타압의 순서를 정수 값으로 리턴한다.
@Test
void isEqualsOrdinal() {
Role adminRole = Role.ADMIN;
int adminOrdinal = adminRole.ordinal();
assertEquals(adminOrdinal, 0);
}
만약 enum 클래스 내의 순서를 변경하면 위 테스트는 어떻게 동작할까?
public enum Role {
ADMIN, GENERAL; // AS-IS
}
public enum Role {
GENERAL, ADMIN; // TO-BE
}
enum 클래스 내부 열거 형들의 순서가 바뀜에 따라, 앞서 작성된 테스트 코드가 실패함을 볼 수 있다.
따라서 ordinal 메소드를 사용하는 것은 가능하면 지향하자. (아래 Effective Java에서 예제를 자세히 설명해준다.)
[Effective Java 3/E Item 35. ordinal 메서드 대신 인스턴스 필드를 사용하라]
EnumSet
EnumSet은 AbstractSet을 상속받고 있는 추상 클래스이다.
EnumSet은 다른 컬렉션들과 다르게, new 연산자를 사용하지 않고(abstract 키워드가 사용됨), 정적 팩토리 메소드 (static factory method)로 구현 객체를 반환받을 수 있다.
@Test
void enumSetEmptyTest() {
EnumSet<Role> noneOfEnums = EnumSet.noneOf(Role.class);
EnumSet<Role> allOfEnums = EnumSet.allOf(Role.class);
Stream.of(noneOfEnums).forEach(System.out::println);
Stream.of(allOfEnums).forEach(System.out::println);
}
Leave a comment