enum이란?
enum은 우리나라말로 열거 타입이라 말하며, 자바의 참조타입 중 하나이다. 열거는 몇 가지 한정된 필드값을 나열한 것으로 그 필드값을 우리는 상수(enumeration constant)라고 부른다. 상수는 변하지 않는 값을 의미하여, 그런 의미를 가질 수 있게 된 이유는, 우리는 enum을 일정 조건에서 기대되거나 한정되는 것들을 미리 나열하고 고정하고 꺼내쓰기 위한 용도로 사용되기 때문이다. 그러므로 우리는 해당 타입과 그것의 값만을 보더라도 일관성 있게 이해하고 사용할 수 있다.
enum의 정의와 사용
2.1 enum의 이름 표기
public enum Season {
SPRING, SUMMER, AUTUMN, WINDER
}
public enum MyStatus {
WORKING,
STUDYING,
TAKING_A_REST,
TAKING_A_BATH,
HAVING_LUNCH,
WORKING_OUT,
DRIVING
}
enum의 상수는 대문자로 표기한다. 띄어쓰기가 필요할 경우 카멜표기법을 대신하여 언더바_를 사용한다.
2.2 enum의 정의 및 호출
Season january = Season.WINTER;
Season now = Season.WINTER;
boolean vali = now == january;
System.out.println("1월의 계절은 : "+january);
System.out.println("지금의 계절은 : "+now);
System.out.println("1월의 계절은 지금과 같나요? : "+vali);
결과:
1월의 계절은 : WINTER
지금의 계절은 : WINTER
1월의 계절은 지금과 같나요? : true
2.3 enum의 상수는 모두 생성자로서 힙에 저장된다.
public enum Season {
SPRING, SUMMER, AUTUMN, WINTER;
Season() {
System.out.println("생성자 호출 : "+this.toString());
}
}
....main thread...
Season january = Season.WINTER;
결과:
생성자 호출 : SPRING
생성자 호출 : SUMMER
생성자 호출 : AUTUMN
생성자 호출 : WINTER
위의 Season 클래스는 생성자가 호출될 경우 "생성자 호출"이라는 문장을 콘솔에 출력하도록 해놨다. 그래서 참조변수 january를 생성했을 때, 객체 4개가 생성된 것을 확인할 수 있다.
이는 내부적으로 아래와 같은 과정을 거친다고 한다.
-> Season 클래스 호출
-> 각 상수에 따라 객체 생성
-> method area의 필드값 Season.SPRING은 heap의 해당 객체를 주소로 가지고 있음.
-> Season january = Season.SPRING; 은 주소를 복사하는 과정.
그러므로 아래의 코드와 같이 참조변수 두 개를 동등연산자로 비교하면 같다고 나온다. 이는 힙 영역의 같은 객체인 SUNDAY를 참조하기 때문이다.
Season january = Season.WINTER;
Season now = Season.WINTER;
boolean vali = (now == january);
System.out.println("1월의 계절은 : "+january);
System.out.println("지금의 계절은 : "+now);
System.out.println("1월의 계절은 지금과 같나요? : "+vali);
결과:
1월의 계절은 : WINTER
지금의 계절은 : WINTER
1월의 계절은 지금과 같나요? : true
java.lang.Enum 클래스와 메서드
모든 enum 타입은 Enum 클래스를 상속하도록 되어 있다. 그러므로 Enum 클래스를 통하지 않고 해당 참조변수의 객체를 탱해 매서드를 호출 할 수 있다.
3.1 ordinal()
enum 타입은 각각의 상수를 순서로서 가지고 있다. 그러므로 ordinal()을 통해 해당 객체의 순서를 알 수 있다.
(조금 뜬금 없지만..) 스프링의 어너테이션 중 하나인 @Enumerated는 두 가지 타입을 가진다. EnumType.STRING, EnumType.ORDINAL. 둘 중 하나를 선택할 수 있는데, 만약 순서(ordinal)를 그 값으로 하면, jpa는 데이타베이스의 해당 값을 숫자로 저장한다. 만약 그렇게 했다, enum의 상수의 순서가 틀어지면 문제가 발생할 수 있으므로 꼭 String으로 해야한다.
3.2 valueOf()
ordinal이 순서에 따라 값을 출력한다면, valueOf()는 그것의 값을 통해 값을 출력한다.
Season now = Season.valueOf("SPRING");
System.out.println(now);
-> 결과 : SPRING
3.3 values()
values는 enum 타입 모든 객체를 배열로 만든다.
Season[] seasons = Season.values();
for (Season season : seasons) {
System.out.println(season);
}
-> 결과 :
SPRING
SUMMER
AUTUMN
WINTER