[JAVA] 이것이 자바다_4

Updated:

JAVA의 열거 타입에 대해 알아보자.

열거 타입이란?


데이터 중에는 몇 가지로 한정된 값만을 갖는 경우가 흔히 있다.
예를 들어 요일에 대한 데이터는 월, 화, 수, 목, 금, 토, 일이라는 일곱 개의 값만을 갖고, 계절에 대한 데이터는 봄, 여름, 가을, 겨울이라는 네 개의 값만을 가진다.
이와 같이 한정된 값만을 갖는 데이터 타입을 열거 타입(enumeration type) 이라고 한다. 열거 타입은 몇 개의 열거 상수 중에서 하나의 상수를 저장하는 데이터 타입이다.


열거 타입 선언


열거 타입을 선언하기 위해서는 먼저 열거 타입의 이름을 정하고 열거 타입 이름으로 소스 파일(.java)를 생성해야 한다.
열거 타입 이름은 관례적으로 첫 문자를 대문자로 하고 나머지는 소문자로 구성한다.
여러 단어로 구성된 이름이라면 단어 첫 문자를 대문자로 한다.
다음은 예시로 만들어진 열거 타입 소스 파일들의 이름이다.

Week.java
MemberGrade.java
ProductKind.java

소스 파일의 내용으로는 다음과 같이 열거 타입 선언이 온다.
public enum 키워드는 열거 타입을 선언하기 위한 키워드이다. 반드시 소문자로 작성해야 한다.
열거 타입 이름은 소스 파일명과 대소문자가 일치해야 한다.

public enum 열거타입이름 {...}

열거 타입을 선언했다면 열거 상수를 선언한다.
열거 상수는 열거 타입의 값으로 사용되며, 관례적으로 모두 대문자로 작성한다.

public enum Week {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, ...}

만약 열거 상수가 여러 단어로 구성될 경우에는 단어 사이를 _로 연결한다.
다음은 예시이다.

public enum LoginResult {LOGIN_SUCCESS, LOGIN_FAILED}

열거 타입 변수


열거 타입을 선언했다면 이제 열거 타입을 사용할 수 있다.
열거 타입도 하나의 데이터 타입이므로 변수를 선언하고 사용해야 한다.
예를 들어 열거 타입 Week로 변수를 선언하면 아래와 같다.

Week today;
Week reservationDay;

열거 타입 변수를 선언했다면 다음과 같이 열거 상수를 저장할 수 있다.
열거 상수는 단독으로 사용할 수는 없고 반드시 열거타입.열거상수로 사용된다.
예를 들어 today 열거 변수에 열거 상수인 SUNDAY를 저장하면 아래와 같다.

Week today = Week.SUNDAY;

열거 타입 변수는 null 값을 저장할 수 있는데 열거 타입도 참조 타입이기 때문이다.

Week birthday = null;

참조 타입 변수는 객체를 참조하는 변수이다.
그렇다면 열거 상수는 객체일까?
그렇다.
열거 상수는 열거 객체로 생성된다.
열거 타입 Week의 경우 MONDAY부터 SUNDAY까지의 열거 상수는 다음과 같이 총 7개의 Week 객체로 생성된다.
그리고 메소드 영역에 생성된 열거 상수가 해당 Week 객체를 각각 참조하게 된다.

그렇다면 다음 코드를 어떻게 이해하면 좋을까?

Week today = Week.SUNDAY;

열거 타입 변수 today는 스택 영역에 생성된다.
today에 저장되는 값은 Week.SUNDAY 열거 상수가 참조하는 객체의 번지이다.
따라서 Week.SUNDAY와 today 변수는 서로 같은 Week 객체를 참조하게 된다.

그렇기 때문에 today 변수와 Week.SUNDAY 상수의 == 연산 결과는 true가 된다.

today == Week.SUNDAY    // true

다음과 같은 경우도 알아두자.

Week week1 = Week.SATURDAY;
Week week2 = Week.SATURDAY;
System.out.println( week1 == week2 );   // true

열거 객체의 메소드


열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있다.
아래의 표는 열거 객체가 가지는 데이터 및 메소드들을 보여준다.

리턴 타입 메소드(매개 변수) 설명
String name() 열거 객체의 문자열을 리턴
int ordinal() 열거 객체의 순번(0부터 시작)을 리턴
int compareTo() 열거 객체를 비교해서 순번 차이를 리턴
열거 타입 valueOf(String name) 주어진 문자열의 열거 객체를 리턴
열거 배열 values() 모든 열거 객체들을 배열로 리턴

이제 메소드를 하나씩 천천히 알아보도록 하자.


name() 메소드


name() 메소드는 열거 객체가 가지고 있는 문자열을 리턴한다.
이때 리턴되는 문자열은 열거 타입을 정의할 때 사용한 상수 이름과 동일하다.

아래 코드는 today가 참조하는 열거 객체에서 name() 메소드를 호출하여 문자열을 얻어낸다.
name() 메소드는 열거 객체 내부의 문자열인 “SUNDAY”를 리턴하고 name 변수에 저장한다.

Week today = Week.SUNDAY;
String name = today.name();

ordinal() 메소드


ordinal() 메소드는 전체 열거 객체 중 몇 번째 열거 객체인지 알려준다.
열거 객체의 순번은 열거 타입을 정의할 때 주어진 순번을 말하는데, 0번부터 시작한다.

아래 코드는 today가 참조하는 열거 객체가 전체 열거 객체에서 몇 번째 순번인지 알아내는 코드이다.
ordinal() 메소드는 6을 리턴해서 ordinal 변수에 저장한다.

Week today = Week.SUNDAY;
int ordinal = today.ordinal();

compareTo() 메소드


compareTo() 메소드는 매개값으로 주어진 열거 객체를 기준으로 전후로 몇 번째 위치하는지를 비교한다.
만약 열거 객체가 매개값의 열거 객체보다 순번이 빠르다면 음수가, 순번이 늦다면 양수가 리턴된다.
아래 코드는 day1과 day2의 상대적 위치를 비교하는 코드이다.

day1.compareTo(day2)는 day2를 기준으로 day1의 상대적 위치를 리턴한다.
day1(순번:0)이 day2(순번2)보다 앞에 위치하고 순번 차이가 2이므로 result1은 음수 -2가 저장된다.

그러나 day2.compareTo(day1)은 day1을 기준으로 day2의 상대적 위치를 리턴한다.
따라서 day2가 day1보다 뒤에 위치하고 순번 차이가 2이므로 result2는 2가 저장된다.

Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;
int result1 = day1.compareTo(day2); // -2
int result2 = day2.compareTo(day1); // 2

valueOf() 메소드


valueOf() 메소드는 매개값으로 주어지는 문자열과 동일한 문자열을 가지는 열거 객체를 리턴한다.
이 메소드는 외부로부터 문자열을 입력받아 열거 객체로 변환할 때 유용하게 사용된다.

아래 코드에서 weekDay 변수는 Week.SATURDAY 열거 객체를 참조하게 된다.

Week weekDay = Week.valueOf("SATURDAY");

values() 메소드


values() 메소드는 열거 타입의 모든 열거 객체들을 배열로 만들어 리턴한다.

아래는 Week 열거 타입의 모든 열거 객체를 배열로 만들어 향상된 for문을 이용해서 반복하는 코드이다.

Week[] days = Week.values();
for(Week day : days){
    System.out.println(day);
}

배열의 인덱스는 열거 객체의 순번과 같고 각 인덱스 값은 해당 순번의 열거 객체 번지이다.


JAVA의 열거 타입을 정리해보았다.
enum은 본 적은 있었지만, 사용해본 경험도 없었고 중요하다는 생각을 못했었다.
근데 잘 쓰면 좋을 것 같은 타입인 것 같다.
어디에도 쓰일 수 있기 때문에 잘 정리해두자.

Leave a comment