⛏️/JAVA
[JAVA] 35. enum_type
defyuil
2023. 10. 25. 12:55
상수를 사용하여 한정된 데이터를 관리하는 경우 간편한 선언을 통해 관리할 수 있다는 장점이 있으나 해당 값의 범위를 벗어나는 값을 사용할 경우 컴파일 시점에서 오류 발견이 불가능! 추가적인 작업을 통해 범위 내의 값인지 판별하는 작업이 별도로 필요함
=> 이를 해결하기 위해 열거형(enum type) 필요
열거형(Enumeration Type = Enum 타입)
- 상수를 좀 더 확실한 형태로 다루기 위한 객체의 일종
- 데이터타입이 일치하면 다른 데이터라도 사용 가능한 상수의 단점을 해결
- enum 타입은 내부적으로 java.lang.Enum 클래스를 상속받음
< 열거타입 정의 방법 >
[접근제한자] enum 열거타입명 {
// 열거타입에 사용할 값(상수)을 차례대로 나열
상수1, 상수2, ... 상수n
}
- 기본적으로 클래스, 인터페이스 정의 문법과 유사함
단, 열거타입 중괄호 내에는 상수로 사용될 이름만 지정
< 열거 타입 사용 방법 >
1. 열거타입 변수 선언 방법(클래스, 인터페이스와 동일)
열거타입명 변수명
ex) Month month, EnumWeek today
2. 열거타입 비교 방법
- if문 사용 시 동등비교 연산자 사용(==)
- switch문 사용 가능(단, case 문에서 열거타입명 없이 상수만 지정 필수!)
switch(열거타입변수) {
case 열거타입상수1 : 수행할 작업들...;
case 열거타입상수2 : 수행할 작업들...;
...
case 열거타입상수n : 수행할 작업들...;
}
요일 정보를 관리하는 클래스 정의
// 열거타입을 사용하지 않고, 상수만 사용하는 경우
// (요일은 7가지로 정해져 있으므로 상수로 처리 가능)
class Week {
// 요일 정보를 상수로 관리
// => 외부에서 실제 데이터를 정확하게 알지 못해도 상수명(변수명)
// 만으로 값을 사용 가능
// => 클래스명만으로 사용이 가능하여 접근이 쉬움.
// 또한, 값 변경이 불가능하여 안전함.
public static final int WEEK_MONDAY = 0;
public static final int WEEK_TUSEDAY = 1;
public static final int WEEK_WEDNESDAY = 2;
public static final int WEEK_THURSDAY = 3;
public static final int WEEK_FRIDAY = 4;
public static final int WEEK_SATURDAY = 5;
public static final int WEEK_SUNDAY = 6;
private int myWeek;
public int getMyWeek() {
return myWeek;
}
public void setMyWeek(int myWeek) {
// this.myWeek = myWeek;
// 요일에 대한 정상 범위 판별 없이 저장 작업을 수행하는 경우
// 실제 저장된 요일을 꺼내서 사용하는 시점에서는 문제가 발생할 수 있다!
// 따라서, 조건문 등을 사용하여 전달받은 파라미터값에 대한 검증이 추가적으로 필요하다
if(myWeek >= WEEK_MONDAY && myWeek <= WEEK_SUNDAY) {
this.myWeek = myWeek;
} else {
System.out.println("요일 입력 에러!");
}
Week week = new Week();
// Setter 메서드를 호출해서 파라미터로 요일 전달 시 정확한 정수값을 몰라도
// 상수 호출만으로 해당 정수 사용 및 전달이 가능
week.setMyWeek(Week.WEEK_WEDNESDAY); // 수요일(2) 설정
if(week.getMyWeek() == Week.WEEK_WEDNESDAY) {
System.out.println("오늘은 수요일 입니다!");
}
// 요일 정보를 상수로 관리하는 경우의 문제점
// => 상수 데이터들이 정수일 경우 해당 정수를 전달받는 메서드(Setter) 호출 시
// 상수 범위 값이 아닌 다른 값을 전달해도 컴파일에러(문법적 오류)가 발생하지 않음
week.setMyWeek(10); // 10이라는 정수값을 갖는 요일은 없으나,
// int 타입 파라미터이므로 컴파일 시점에서는 아무런 문제가 발생하지 않는다.
// 그러나, 해당 데이터를 사용하기 위한 시점에서는 문제가 발생할 수 있다!
// => 따라서, 별도로 해당 범위 내의 데이터인지 판별하는 추가적인 작업을 수행해야 함
열거 타입 정의
enum EnumWeek {
// 열거형 정의 시 중괄호 내부에는 값을 갖는 상수 이름만 나열함
// (별도의 값을 지정하지 않는다!)
MONDAY, TUSEDAY, WEDENSDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
열거 타입을 사용하는 클래스 정의
class MyCalendar {
EnumWeek myWeek;
// => 클래스 내에서 열거타입 변수 선언 가능(로컬변수도 가능)
public EnumWeek getMyWeek() {
return myWeek;
}
public void setMyWeek(EnumWeek myWeek) {
this.myWeek = myWeek;
}
}
// 열거타입 변수 today 선언 및 초기화 후 호출
EnumWeek today = EnumWeek.WEDENSDAY;
System.out.println(today);
// 열거타입을 활용하는 클래스 사용
MyCalendar mc = new MyCalendar();
mc.setMyWeek(today);
System.out.println("오늘의 요일: " + mc.getMyWeek());
mc.setMyWeek(EnumWeek.WEDENSDAY);
System.out.println("오늘의 요일: "+ mc.getMyWeek());
// 열거 타입 사용 시 장점
// => 정의 시 지정된 상수 외의 다른 값은 절대 전달 불가능!
// mc.setMyWeek(5);
// => he method setMyWeek(EnumWeek) in the type MyCalendar
// is not applicable for the arguments (int)
// mc.setMyWeek("WEDENSDAY"); (X)
// mc.setMyWeek(WEDENSDAY); (X)
// => 반드시 열거타입명.상수명으로 지정된 값만 전달해야 한다!
mc.setMyWeek(EnumWeek.WEDENSDAY);
enum 상수 연산 및 메서드
- enum 상수 값은 동등비교연산자(==) 로 일치 여부 비교 가능하며, switch ~ case 문에도 enum 타입 비교가 가능함
- enu 타입 상수에는 각각 ordinal(순서번호) 값이 자동 부여됨
=> 0부터 부여됨
=> enum 객체의 ordinal() 메서드를 통해 얻을 수 있음
EnumWeek today = EnumWeek.WEDENSDAY;
if(today == EnumWeek.WEDENSDAY) {
System.out.println("수요일입니다!");
} else {
System.out.println("수요일이 아닙니다!");
}
// enum 타입 객체는 switch 문에 전달 가능
switch(today) {
// case 문을 사용하여 enum 상수를 지정하면 비교 가능
// => 주의! enum타입명.상수 가 아닌 그냥 상수 자체를 비교
// case EnumWeek.MONDAY :
case MONDAY : System.out.println("월요일입니다!"); break;
case TUSEDAY : System.out.println("화요일입니다!"); break;
case WEDENSDAY : System.out.println("수요일입니다!"); break;
case THURSDAY : System.out.println("목요일입니다!"); break;
case FRIDAY : System.out.println("금요일입니다!"); break;
case SATURDAY : System.out.println("토요일입니다!"); break;
case SUNDAY : System.out.println("일요일입니다!"); break;
}
System.out.println("====================================");
// ordinal() : 상수의 순서 번호를 정수로 리턴
System.out.println("오늘의 ordinal 값: " + today.ordinal());
if(today.ordinal() < 4) {
System.out.println("수업 언제 끝나나...");
} else if(today.ordinal() == 4) {
System.out.println("오늘은 금요일! 그래도 내일은 쉰다!");
} else {
System.out.println("아싸! 휴일!");
}
// name(): 상수명을 문자열로 리턴
String strToday = today.name();
System.out.println(strToday);
TEST