상수를 사용하여 한정된 데이터를 관리하는 경우 간편한 선언을 통해 관리할 수 있다는 장점이 있으나 해당 값의 범위를 벗어나는 값을 사용할 경우 컴파일 시점에서 오류 발견이 불가능하다.
이 경우 추가적인 작업을 통해 범위 내의 값인지 판별하는 작업이 필요한데 이때 열거형(enum_type)이 필요하다.
상수를 좀 더 확실한 형태로 다루기 위한 객체의 일종
데이터타입이 일치하면 다른 데이터라도 사용 가능한 상수의 단점을 해결
enum 타입은 내부적으로 java.lang.Enum
클래스 상속받음
한정된 데이터를 사용하는 경우 열거형으로 묶어주면 편함
-> ex) 계절, 요일···
열거 타입 정의 방법
[접근제한자] enum 열거타입명 { 상수1, 상수2, ... , 상수n // 열거타입에서 사용할 값을 차례대로 나열함 }
public static void main(String[] args) {
EnumWeek today = EumWeek.TUE;
Week w = new Week();
w.setMyWeek(today);
System.out.println("오늘의 요일 : " + w.getMyWeek();)
// THU 출력됨
}
enum EnumWeek {
// 열거타입 정의
MON, TUE, WED, THU, FRI, SAT, SUN
// 중괄호 내에는 값을 갖는 상수 이름만 나열함!
// 별도의 값 지정하지 않음!
}
class Week {
// 열거타입을 사용하는 클래스 정의
EnumWeek myWeek;
// 열거타입의 변수 선언 가능함
// 멤버변수 말고도 로컬변수로도 선언 가능
public EnumWeek getMyWeek() {
return myWeek;
}
public void setMyWeek(EnumWeek myWeek) {
this.myWeek = myWeek;
}
// getter와 setter 정의
}
열거 타입 사용 시
setXXX()
메서드를 이용하여 값을 입력할 때 지정된 상수 외의 다른 값은 전달 불가능!
또한 반드시열거타입명.상수명
으로 지정된 값 전달가능!
w.setMyWeek(EnumWeek.SAT);
: ⭕
w.setMyWeek(5);
: ❌
⭐ EnumWeek 타입 객체가 Enum 클래스의 서브 클래스 타입 객체인지 판별
if(today instanceof Enum) {
System.out.printl("Enum 클래스의 서브클래스이다");
} else {
System.out.printl("Enum 클래스의 서브클래스가 아니다");
}
📌 출력
Enum 클래스의 서브클래스이다
열거 타입 변수 선언 방법
클래스, 인터페이스와 동일
열거타입명 변수명
열거 타입 비교 방법
if문 사용 시 동등 비교 연산자 사용
switch문 사용 가능
(단, case문에서 열거타입명 없이 상수만 지정)
switch(열거타입변수) {
case 열거타입상수1 : 수행할 작업들;
case 열거타입상수2 : 수행할 작업들;
case 열거타입상수n : 수행할 작업들;
}
요일 정보를 상수로 관리할 때의 장점
외부에서 실제 데이터(정수값)을 정확하게 알지 못하더라도 변수명만으로 값 사용 가능
클래스명만으로 접근이 가능하기 때문에 접근 쉬움
값 변경 불가능하여 안전
요일 정보를 상수로 관리하는 경우의 문제점
상수 데이터들이 정수일 경우 해당 정수를 전달받는 메서드(Setter) 호출 시 상수 범위 값이 아닌 값을 전달하더라도 컴파일 에러가 발생하지 않음
-> 해당 범위 내의 데이터인지 판별하는 작업 필요
public static void main(String[] args) {
Week w = new Week();
w.setMyWeek(Week.WEEK_TUE);
// 정확한 값을 몰라도 클래스명.변수명으로 사용 가능
}
class Week{
public static final int WEEK_MON = 0;
public static final int WEEK_TUE = 1;
public static final int WEEK_WED = 2;
public static final int WEEK_THU = 3;
public static final int WEEK_FRI = 4;
public static final int WEEK_SAT = 5;
public static final int WEEK_SUN = 6;
// 요일 정보를 상수로 관리함
private int myWeek;
public int getMyWeek() {
return myWeek;
}
public void setMeWeek(int myWeek) {
// this.myWeek = myWeek;
// 이 코드를 그대로 사용할 경우 저장된 값을 꺼낼 때 문제 발생함
// 저장되지 않은 값을 꺼내려고 하는 거니까...
// 그래서 미리 전달받은 파라미터에 대한 검증이 필요함
if(myWeek >= WEEK_MON && myWeek <= WEEK_SUN) {
this.myWeek = myWeek;
// 파라미터가 월요일부터 일요일 사이의 값일 때만 저장
}else{
System.out.println("요일 입력 오류");
// 그 외의 값은 저장 안되게 함
}
}
}
enum 상수 값은 동등비교연산자로 일치 여부 비교 가능
switch ~ case
문에서도 enum 타입 비교 가능
enum 타입 상수에는 ordinal(순서번호) 값이 자동으로 부여됨
-> 0부터 시작
-> enum 객체의 ordinal()
메서드 통해 사용 가능
public static void main(String[] args) {
EnumWeek today = EnumWeek.TUE;
if(today == EnumWeek.TUE) { // if문 사용
System.out.println("화요일이 맞습니다");
}else {
System.out.println("화요일이 아닙니다");
}
switch(today) { // switch~case문 사용
case MON : System.out.println("월요일 입니다");
break;
case TUE : System.out.println("화요일 입니다");
break;
case WED : System.out.println("수요일 입니다");
break;
case THU : System.out.println("목요일 입니다");
break;
case FRI : System.out.println("금요일 입니다");
break;
case SAT : System.out.println("토요일 입니다");
break;
case SUN : System.out.println("일요일 입니다");
break;
}
System.out.println("today.ordinal 값 : " + today.ordinal());
// 1 출력됨
// 월요일(0)부터 시작되니까!
String strDay = today.name();
// 상수명을 문자열로 리턴해줌
System.out.println(strDay);
// TUE 출력됨
}
enum EnumWeek {
MON, TUE, WED, THU, FRI, SAT, SUN
}
생성자를 이용해 상수에 다른 값 결합하기
public static void main(String[] args) {
Month now = Month.JAN;
System.out.println(now + ", " + now.getMonthName());
}
enum Month {
JAN("1월"), FEB("2월");
// 단독으로 정의 시 오류 발생
// 생성자 정의 필수!
private String monthName;
public Month(String monthName) {
// 생성자 정의
this.monthName = monthName;
}
public String getMonthName() {
return monthName;
}
public void setMonthName(String monthName) {
this.monthName = monthName;
}
}