[자바] enum_type

Gammi·2022년 11월 29일
0

JAVA

목록 보기
31/35

상수를 사용하여 한정된 데이터를 관리하는 경우 간편한 선언을 통해 관리할 수 있다는 장점이 있으나 해당 값의 범위를 벗어나는 값을 사용할 경우 컴파일 시점에서 오류 발견이 불가능하다.

이 경우 추가적인 작업을 통해 범위 내의 값인지 판별하는 작업이 필요한데 이때 열거형(enum_type)이 필요하다.




📚 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 상수 연산 및 메서드


  • 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;
  }
}
profile
개발자가 되었어요⭐️

0개의 댓글