enum이란


enum이란 enumerated type 즉 열거 타입을 의미한다. 프로그래밍을 짜다 보면 데이터 중에 몇 가지 한정된 값을 갖는 경우가 흔히 있다. 예를 들어 계절, 요일 등이 있으며, 계절에는 봄, 여름, 가을, 겨울 그리고 요일에는 월, 화, 수, 목, 금, 토, 일 이라는 한정된 값을 가지게 된다. 이러한 한정된 상수를 정의할 시 final static과 같은 방식으로 정의를 많이 하였지만 이러한 방법으로 상수를 정의해서 프로그램을 짜게 되면 다양한 문제점이 발생된다.

public class Season {

   public static final int SPRING = 0;
   public static final int SUMMER = 1;
   public static final int AUTUMN = 2;
   public static final int WINTER = 3;

   private final int stateCode;

   public State(int stateCode) {
	   this.stateCode = stateCode;
   }

   public int getStateCode() {
	   return this.stateCode;
   }

}

public class Main {

   public static void main(String[] args) {
		
      Season spring = new Season(Season.SPRING); 
      Season summer = new Season(Season.SUMMER);
      Season autumn = new Season(Season.AUTUMN);
      Season winter = new Season(Season.WINTER);
      Season stateExcep = new Season(4);
		
      System.out.println("spring: " + spring.getStateCode());
      System.out.println("summer: " + summer.getStateCode());
      System.out.println("autumn: " + autumn.getStateCode());
      System.out.println("stateExcep: " + stateExcep.getStateCode());
   }

}

위 코드를 보게 되면 계절에 대한 class를 정의하고 계절에 대해 정의된 상태 값을 사용하여 객체를 생성하였다. 하지만 main메소드에서 봄, 여름, 가을, 겨울을 나타내는 0~3까지의 상태 값을 벗어난 4라는 값을 사용하여 객체를 생성하였지만 int 타입의 변수에 int타입의 데이터가 할당되었으니 컴파일 과정에서 에러를 잡을 수 없게 된다. 이는 결국 프로그래머가 의도하지 않은 동작을 문제없이 수행하면서 프로젝트 상의 큰 문제들을 야기하게 된다.

public enum Season {

   SPRING(0), SUMMER(1), AUTUMN(2), WINTER(3);

   final private int stateCode;

   private Season(int stateCode){
       this.stateCode = stateCode;
   }
	
   public int getStateCode() {
       return this.stateCode;
   }

}

public class Main {

   public static void main(String[] args) {
		
       Season spring = Season.SPRING;
       Season summer = Season.SUMMER;
       Season autumn = Season.AUTUMN;
       Season winter = Season.WINTER;
       Season stateExcep2 = 3;  // 타입 에러 발생
		
       System.out.println("spring: " + spring.getStateCode());
       System.out.println("summer: " + summer.getStateCode());
       System.out.println("autumn: " + autumn.getStateCode());
       System.out.println("winter: " + winter.getStateCode());
		
	}
}

위 코드는 class로 정의한 것을 이번에는 enum을 사용하여 계절을 정의한 것이다. enum class를 사용하여 각 계절의 상태 값을 int로 정의하여 데이터를 할당했다. 그리고 main메소드에서 enum class에서 상태 값으로 정의한 값(0~3) 이외의 값을 정의하자 타입 에러가 발생하여 그 외의 값을 사용할 수 없게 되었다. 이와 같이 final static을 사용하였을 시 발생하는 문제점을 enum을 사용하므로 방지할 수 있게 된다.

 

enum의 장점


enum을 사용하게 되면 다음과 같은 장점이 있다.

  • 코드가 단순해지며 가독성이 좋다.
  • 인스턴스 생성과 상속을 방지하여 상수값의 타입 안정성이 보장된다.
  • enum class를 사용하여 새로운 상수들의 타입을 정의함으로 정의한 타입 이외의 타입을 가진 데이터 값을 컴파일 시 체크한다.
  • 키워드 enum을 사용하기 때문에 구현의 의도가 열거임을 분명하게 알 수 있다.

 

enum 정의하는 방법


○enum은 별도의 java파일, 클래스 내부, 클래스 외부에 다음과 같이 정의할 수 있다.

//생성자가 있는 없는 경우

enum 열거형이름 { 
   상수명1, 상수명2, .... 상수명n; 
}

//생성자가 없는 경우

enum 열거형 이름 {
   상수명1(), 상수명2(), .... 상수명n();
   
   private final 데이터 타입 변수명;
   
   private 생성자(매개변수1) {}

}

생성자를 선언할 경우 private 타입으로 정의해야 한다(public, default, protected의 경우 컴파일 에러 발생함). Enum은 고정된 상수들의 집합으로 런타임이 아닌 컴파일 타임에 모든 값에 대해 알아야 한다. 즉, 다른 패키지나 클래스에서 Enum 타입에 접근해서 동적으로 어떤 값을 정해줄 수 없으며, 할당할 수 있게 되면 확장의 가능성이 커지면서 문제가 발생할 수 있게 된다.

 

 

○정의한 enum의 사용법

//생성자가 없는 경우

enum Fruits{
    APPLE, BANANA, ORANGE;
}

public class EnumPractice {
    public static void main(String[] args) {
        System.out.println(Fruits.APPLE);
        System.out.println(Fruits.BANANA);
        System.out.println(Fruits.ORANGE);
    }
}

=====================출력결과=====================
APPLE
BANANA
ORANGE

//생성자가 있는 경우

enum Fruits{
    APPLE("red") ,
    BANANA("yellow"),
    ORANGE("orange");

    private final String color;

    public String getColor() {
        return color;
    }

    Fruits(String color) {
        this.color = color;
    }
}

public class EnumPractice {
    public static void main(String[] args) {
        System.out.println(Fruits.APPLE);
        System.out.println(Fruits.APPLE.getColor());
        System.out.println(Fruits.BANANA);
        System.out.println(Fruits.BANANA.getColor());
        System.out.println(Fruits.ORANGE);
        System.out.println(Fruits.ORANGE.getColor());
    }
}

========================출력결과========================
APPLE
red
BANANA
yellow
ORANGE
orange

○enum의 주요 메소드

메소드 내용
String  name() 해당 상수의 이름을 문자열로 변환하여 리턴
String toString() 해당 상수의 이름을 문자열로 변환하여 리턴
int  ordinal() 해당 열거체 상수가 열거체 정의에서 정의된 순서(0부터 시작)를 리턴
values() 해당 열거체의 모든 상수를 저장한 배열을 생성하여 리턴
enum Fruits{
    BANANA("yellow"), APPLE("red"), ORANGE("orange");

    private final String color;

    private Fruits(String color) {
        this.color = color;
    }

}

public class EnumPractice {
    public static void main(String[] args) {
        System.out.println(Fruits.BANANA);
        System.out.println(Fruits.APPLE);
        System.out.println(Fruits.ORANGE);
        System.out.println("============================");

        System.out.println(Fruits.BANANA.toString());
        System.out.println(Fruits.APPLE.toString());
        System.out.println(Fruits.ORANGE.toString());
        System.out.println("============================");

        System.out.println(Fruits.BANANA.name());
        System.out.println(Fruits.APPLE.name());
        System.out.println(Fruits.ORANGE.name());
        System.out.println("============================");

        System.out.println(Fruits.BANANA.ordinal());
        System.out.println(Fruits.APPLE.ordinal());
        System.out.println(Fruits.ORANGE.ordinal());
        System.out.println("============================");

        Fruits[] values = Fruits.values();

        for (Fruits fr : values) {
            System.out.println(fr);
        }
    }
}

 

'JAVA' 카테고리의 다른 글

Stream  (0) 2022.07.25
람다식(Lambda Expression)  (0) 2022.07.17
JAVA 실행과정 & JVM  (0) 2022.01.09
예외 처리  (0) 2022.01.05
예외  (0) 2022.01.01

+ Recent posts