본문 바로가기

Java 기본 문법 - 참조 서적 [이것이 자바다 - 한빛미디어]/3. 참조 타입

8. Java 자바 참조 타입 - 열거 타입

열거 : 한정된 값만을 갖는 데이터 타입으로 몇 개의 열거 상수 중에서 하나의 상수를 저장하는 데이터 타입이다.

 

열거 예)

 

요일(열거 타입 이름) : 월, 화, 수, 목, 금, 토, 일 (열거 상수)

계절(열거 타입 이름) : 봄, 여름, 가을, 겨울 (열거 상수)

 

 

1. 열거 타입 선언

 

열거 타입을 선언하기 위해서는 열거 타입의 이름을 정하고, 열거 타입 이름으로 소스파일(.java)를 생성해야 한다.

 

열거 타입 이름은 관례적으로 첫 문자를 대문자, 나머지는 소문자로 구성한다.

ex) Week.java,    MemberGrade.java,    ProductKind.java

 

소스파일의 내용으로 열거 타입 선언이 온다.

 


public enum 열거타입이름 {  열거 상수1, 열거 상수2, . . . }

 

- public enum : 열거 타입 선언을 위한 키워드 (반드시 소문자!!)

 

- 열거 타입 이름은 소스 파일명과 대소문자가 모두 일치해야 한다.

 

- 열거 상수는 열거 타입의 값으로 사용되며 모두 대문자로 작성한다.

 


public enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }

 

 

  Week.java

  public enum Week {

      MONDAY,
      TUESDAY,
      WEDNESDAY,
      THURSDAY,
      FRIDAY
      SATURDAY,
      SUNDAY
  }

 

 

열거 상수가 여러 단어로 구성될 경우 단어 사이를 밑줄 _ 로 연결하는 것이 관례이다.

 

public enum LoginResult { LOGIN_SUCCESS, LOGIN_FAILED }

 

* 이클립스에서 열거 타입 생성

 

Package Explorer 뷰에서 프로젝트 선택 후, [File → new → Enum] 을 선택한다.

 

이클립스에서 열거 타입 enum 생성하기

 

 

2. 열거 타입 변수

 

열거 타입을 선언했다면, 열거 타입을 사용할 수 있다.

 

열거 타입도 하나의 데이터 타입이므로 변수를 선언하고 사용해야 한다.

 

- 열거 타입 변수 선언 방법

 

열거타입 변수;

 

ex)

    Week today;

    Week reservationDay;

 

 

- 열거 상수 저장

 

열거 타입 변수를 선언했다면, 열거 상수를 저장할 수 있다.

 

열거 상수는 단독으로 사용할 수 없고 반드시 열거타입.열거상수로 사용된다.

 

열거타입 변수 = 열거타입.열거상수;

 

ex) Week today = Week.SUNDAY;   // today 열거 변수에 열거 상수 SUNDAY 저장

 

 

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

 

Week birthday = null;

 

참조 타입 변수는 객체를 참조하는 변수이므로, 열거 상수 또한 열거 타입 변수가 참조하므로 객체가 된다.

 

즉, 열거 상수는 열거 객체로 생성된다.

 

열거 타입 Week 의 경우 MONDAY 부터 SUNDAY 까지 열거 상수는 총 7개의 Week 객체로 생성된다.

 

이후 메소드 영역에 생성된 열거 상수가 해당 Week 객체를 각각 참조한다.

 

열거 타입이 메모리에 생성되는 방식

 

ex)

    Week today = Week.SUNDAY;

 

열거 타입 변수 today 는 스택 영역에 생성된다.

 

today에 저장되는 값은 Week.SUNDAY 열거 상수가 참조하는 객체의 번지이다.

 

따라서 Week.SUNDAY와 today 변수는 서로 같은 Week 객체를 참조하게 된다.

 

 

메소드 영역의 열거 상수가 참조하는 객체와 스택 영역의 열거 변수가 참조하는 객체는 동일하다.

 

 

today == Week.SUNDAY   // true 출력

 

따라서 같은 번지수 값을 가지므로 == 연산자는 true 가 출력된다.

 

Week week1 = Week.SATURDAY;

Week week2 = Week.SATURDAY;

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

 

 

더보기

자바는 컴퓨터의 날짜 및 요일, 시간을 프로그램에서 사용할 수 있도록 하기 위해 Date, Calendar,  LocalDateTime 등의 클래스를 제공한다.

 

Calendar 클래스를 이용해서 날짜와 시간을 얻는 방법

 

1. Calendar 클래스를 사용하기 위해서는 import 문이 필요하다

 

import java.util.Calendar;

 

2. 먼저 Calendar 변수를 선언하고 Calendar.getInstance( ) 메소드가 리턴하는 Calendar 객체를 얻는다.

 

Calendar now = calendar.getInstance();

 

- Calendar 객체를 얻었다면, get( ) 메소드를 통해서 아래와 같이

 

  년, 월, 일, 요일, 시간, 분, 초를 얻을 수 있다.

 

int year = now.get(Calendar.YEAR);          // 년
int month = now.get(Calendar.MONTH) + 1;    // 월 (1 ~ 12)
int day = now.get(Calendar.DAY_OF_MONTH);   // 일
int week = now.get(Calendar.DAY_OF_WEEK);   // 요일(1 ~ 7)
int hour = now.get(Calendar.HOUR);          // 시간
int minute = now.get(Calendar.MINUTE);      // 분
int second = now.get(Calendar.SECOND);      // 초

 

ex) 현재 날짜 시간 얻기

 

import java.util.Calendar;

public class EnumWeekExam {
    public static void main(String[] args) {
        Week today = null;   // 열거 타입 변수 선언
        
        Calendar cal = Calendar.getInstance();
        int week = cal.get(Calendar.DAY_OF_WEEK);   // (일(1) ~ 토(7) 숫자 반환)
        
        switch(week) {   // 각 요일에 맞는 열거 상수 대입하기
            case 1:
                today = Week.SUNDAY; break; 
            case 2:
                today = Week.MONDAY; break;
            case 3:
                today = Week.TUESDAY; break;
            case 4:
                today = Week.WEDNESDAY; break;
            case 5:
                today = Week.THURSDAY; break;
            case 6:
                today = Week.FRIDAY; break;
            case 7:
                today = today = Week.SATURDAY; break;
        }
        
        System.out.println("오늘 요일: "+ today);
        
        if(today == Week.SUNDAY) {
            System.out.println("일요일에는 축구를 합니다.");
        } else {
            System.out.println("열심히 자바 공부를 합니다.");
        }
    }
}

 

 

 

3. 열거 객체의 메소드

 

열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있다.

 

열거 객체가 가지는 데이터 및 메소드는 아래 그림과 같다.

 

 

아래 메소드는  java.lang.Enum 클래스에 선언된 메소드이며

 

모든 열거 타입은 컴파일 시에 Enum 클래스를 상속하도록 되어 있어 모든 열거 객체에서 사용할 수 있다.

 

반환 타입

메소드 ( 매개 변수 )

내용

String

name( )

열거 객체의 문자열 반환

int

ordinal( )

열거 객체의 순번 (0 부터 시작) 을 반환

int

compareTo( )

열거 객체를 비교해서 순번 차이를 반환

열거 타입

valueOf( String name )

주어진 문자열의 열거 객체를 반환

열거 배열

values( )

모든 열거 객체들을 배열로 반환

 

- name( ) 메소드

 

열거 객체가 가지고 있는 문자열을 반환한다.

 

반환되는 문자열은 열거 타입을 정의할 때 사용한 상수 이름과 동일하게 반환된다.

 

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

 

today 열거 타입 변수가 참조하는 열거 객체에서 name( ) 메소드를 호출해서 문자열을 얻어낸다.

 

name( ) 메소드는 열거 객체 내부의 문자열인 "SUNDAY"를 반환하고 name 변수에 저장한다.

 

 

- ordinal( ) 메소드

 

전체 열거 객체 중 몇 번째 열거 객체인지 알려 준다 (순서 번호 반환)

 

열거 타입을 정의할 때 주어진 순번 (0 부터 시작)

 

즉, Week 의 열거 객체 순번은 MONDAY ( 0 ) 부터 SUNDAY ( 6 ) 까지 정의 된다.

 

Week today = Week.SUNDAY;
int ordinal = today.ordinal();  // 6 이 저장된다.

 

 

- compareTo( ) 메소드

 

매개값으로 주어진 열거 객체를 기준으로 전후로 몇 번째 위치하는 지를 비교한다. (상대적 위치 반환)

 

만약 열거 객체매개값의 열거 객체보다 순번이 빠르다면 음수, 순번이 늦다면 양수가 반환된다.

 

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

 

- valueOf( ) 메소드

 

매개값으로 주어지는 문자열과 동일한 문자열을 가지는 열거 객체를 반환한다.

 

외부로 부터 문자열을 입력받아 열거 객체로 변환할 때 유용하게 쓰인다.

 

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

 

weekDay 열거 타입 변수는 Week.SATURDAY 열거 객체를 참조하게 된다.

 

 

- values( ) 메소드

 

열거 타입의 모든 열거 객체들을 배열로 만들어서 반환한다.

 

Week[] days = Week.values();    // Week 열거 타입의 모든 열거 객체를 배열로 만듬

for(Week day : days) {          // 배열 내용 출력
	System.out.println(day);
}

 

 

Week 배열(변수 days)은 아래와 같이 생성된다.

 

열거 객체를 가진 배열로 변환된다. 여기서 배열도 객체이므로 힙 영역에 생성된다.

 

배열의 인덱스열거 객체의 순번과 같고, 각 인덱스 값은 해당 순번의 열거 객체 번지가 들어간다.

 

 

ex) 메소드 사용 예제

 

public class EnumMethodExam {
    public static void main(String[] args) {
    	//name() 메소드
        Week today = Week.SUNDAY;
        String name = today.name();
        System.out.println(name);     // SUNDAY 출력
        
        //ordinal() 메소드
        int ordinal = today.ordinal();
        System.out.println(ordinal);     // 6 출력
        
        //compareTo() 메소드
        Week day1 = Week.MONDAY;
        Week day2 = Week.WEDNESDAY;
        int result1 = day1.compareTo(day2);    
        int ressult2 = day2.compareTo(day1);
        System.out.println(result1);          // -2
        System.out.println(result2);          //  2
        
        //valueOf() 메소드
        if(args.length == 1) {
            String strDay = args[0];
            Week weekDay = Week.valueOf(strDay);
            if(weekDay == Week.SATURDAY || weekDay == Week.SUNDAY) {
                System.out.println("주말 이군요!");
            } else {
                System.out.println("평일 이군요..");
            }
        }
        
        //value() 메소드
        Week[] days = Week.values();
        for(Week day : days) {
            System.out.println(day);   //MONDAY ~ SUNDAY 출력
        }
    }
}