본문 바로가기

Java/Java SE, EE

[Java/Java SE, EE] 열거(Enumeration) 타입

열거(Enumeration) 타입

어떤 변수에 저장되는 값이 몇 가지로 한정되는 경우가 있습니다. 예를 들어 요일을 표시하는 변수에는 월, 화, 수, 목, 금, 토, 일요일 값만 저장하게 됩니다. 또 계절을 표시하는 변수에는 봄, 여름, 가을, 겨울 값만 저장하게 됩니다. 이와 같이 한정된 값 몇 가지를 저장하고 관리하기 위한 변수를 선언할 때, 열거(Enumeration) 타입을 사용 할 수 있습니다. 이 때 열거 타입의 변수에 저장되는 봄, 여름, 가을, 겨울과 같은 값은 열거 상수(Enumeration constant)라고 부르는 리터럴입니다.

public enum Season {
   SPRING,
   SUMMER,
   FALL,
   WINTER
}

열거 타입은 enum 키워드를 사용하여 선언합니다. 열거 타입에 대한 이름은 관례적으로 대문자로 시작하여, 나머지 문자는 소문자를 사용합니다. 열거 타입 내에 선언되는 열거 상수들은 관례적으로 모두 대문자를 사용합니다.

열거 타입을 변수로 사용하는 방법은 클래스에 대한 변수를 선언하는 것과 동일합니다. 

Season season;

열거 타입의 변수에 저장 할 수 있는 값은 해당 열거 타입이 갖는 열거 상수입니다. 열거 상수에 접근하기 위해서는 열거 타입과 열거 상수 이름 사이에 마침표(.)를 구분자로 사용합니다. 이 방법은 클래스의 정적 멤버 변수에 접근하는 방법과 동일합니다.

Season season = Season.SPRING;

열거 타입은 참조(Reference) 타입에 속합니다. 따라서 열거 타입의 변수 역시 null을 저장 할 수 있습니다.

Season season = null;

name

열거 상수의 이름을 리턴하는 멤버 함수입니다. name() 함수는 열거 상수를 선언할 때 사용했던 이름을 그대로 리턴합니다. 

Season season = Season.SUMMER;

System.out.println(season.name()); // SUMMER

이처럼 열거 객체에는 열거 상수를 다루기 위한 기본적은 멤버 함수를 포함하고 있습니다. 이어서 열거 객체에서 사용 할 수 있는 다른 멤버 함수에 대해서 소개하도록 하겠습니다.

ordinal

열거 상수가 열거 타입에서 몇 번째로 정의되었는지에 대한 인덱스를 리턴하는 멤버 함수입니다. 인덱스는 첫 번째로 선언된 열거 상수부터 0으로 시작합니다.

Season season = Season.SUMMER;

System.out.println(season.ordinal());  // 1

equals, 비교 연산자(==)

두 열거 객체는 equal() 함수를 사용하여 비교 할 수 있습니다. equals() 함수는 두 열거 객체가 일치하는 경우 true, 그렇지 않은 경우 false를 리턴합니다.

열거 타입은 앞서 참조 타입에 해당된다고 소개했습니다. 열거 타입은 참조 타입이면서 상수 풀을 사용하는데, 열거 객체를 개발자가 직접 생성(new 생성자 키워드를 사용) 할 수 없기 때문에 모든 열거 객체는 상수 풀에서 참조됩니다. 따라서 래퍼 클래스와 달리 열거 객체는 equals() 함수와 비교 연산자(==)의 결과가 항상 일치합니다.

Season summer = Season.SUMMER;
Season winter = Season.WINTER;

System.out.println(summer.equals(winter)); // false
System.out.println(summer == winter);      // false

System.out.println(summer.equals(summer)); // truee
System.out.println(summer == summer);      // true

compareTo

equals() 함수처럼 두 열거 객체의 일치 여부를 확인 할 수 있는 멤버 함수입니다. equals() 함수와 달리 두 열거 객체의 인덱스(ordinal) 차이를 리턴합니다. 두 열거 객체가 동일한 경우, 인덱스의 차는 0이 됩니다. 즉, compareTo() 함수의 리턴 값이 0인 경우 동일한 열거 객체이며, 그렇지 않은 경우 서로 다른 열거 객체입니다.

System.out.println(spring.compareTo(spring));  // 0
System.out.println(spring.compareTo(summer));  // -1
System.out.println(spring.compareTo(fall));    // -2
System.out.println(spring.compareTo(winter));  // -3
System.out.println(winter.compareTo(spring));  // 3

compareTo() 함수의 인덱스 차는 (함수 호출자 열거 객체의 인덱스 - 인자로 전달된 열거 객체의 인덱스)입니다. 

valueOf

name() 함수는 열거 상수의 이름을 리턴하였습니다. 이와 반대로 valueOf() 함수는 문자열로 이름을 입력하면 열거 상수를 얻을 수 있는 멤버 함수입니다. 

Season spring = Season.valueOf("SPRING");
Season summer = Season.valueOf("summer");  // IllegalArgumentException

이름을 문자열로 전달할 때, 문자열의 대소문자를 엄격하게 구분합니다. 만약 열거 상수에 정의되어 있지 않은 이름은 전달하면 IllegalArgumentExcepion 예외를 발생시킵니다.

values

열거 객체가 사용 할 수 있는 모든 열거 상수를 배열로 리턴하는 멤버 함수입니다. 다음은 values() 함수에 대한 사용 예시입니다.

Season[] seasons = Season.values();

for (int i = 0; i < seasons.length; ++i) {
   System.out.println(seasons[i].ordinal() + " : " + seasons[i].name());
}

코드 실행 결과는 다음과 같습니다. 반복문을 사용하여 열거 상수 배열에 대한 정보를 표시합니다.

0 : SPRING
1 : SUMMER
2 : FALL
3 : WINTER