Enum

kwang·2022년 7월 7일
0

Java-Live-Study

목록 보기
12/15

목표

자바의 열거형에 대해 학습하세요.

학습할 것 (필수)

  • enum 정의하는 방법
  • enum이 제공하는 메소드 (values()와 valueOf())
  • java.lang.Enum
  • EnumSet

enum 정의하는 방법

enum

enum은 서로 관련된 상수를 편리하게 선언하기 위한 것으로 상수를 한번에 여러개 정의할 때 사용한다.
이후 emun은 정의된 값외의 값을 추가할 수 없다.

장점

enum을 사용하면 좋은점을 알아보겠다.

    public class Test() {
        final int APPLE = 1;
        final int BANANA = 2;
        
        int type = 1;
        switch (type){
            case APPLE:
                System.out.println("사과입니다.");
                break;
            case BANANA:
                System.out.println("바나나입니다.");
                break;
        }
    }

우선 위와 같은 코드를 보면 사과와 바나나를 각각 1, 2로 표현했는데 사실 이는 인위적으로 표현한거지 이 둘은 전혀 연관이 없다.

또 아래 코드를 보면 만약 상수에 회사들의 상호를 동시에 사용하는데 같은 이름인 APPLE이 포함 된다면 변수명에 fruit나 company를 붙여 표현해야된다.

    public class Test() {
        final int FRUIT_APPLE = 1;
        final int FRUIT_BANANA = 2;
        
        final int COMPANY_APPLE;
        final int COMPANY_SAMSUNG;
    }

이렇게 연관이 없는 멤버변수들을 같은 클래스에서 사용하기보다 각자 Fruit클래스 Company클래스로 분류해서 작성하게 된다.

    class Fruit{
        final int APPLE = 1;
        final int BANANA = 2;
    }
    
    class Company{
        final int APPLE = 1;
        final int SAMSUNG = 2;
    }

이렇게 상수만 나열한 클래스를 더욱 간편하게 사용 가능하지만 Fruit의 APPLE이랑 Company의 APPLE의 자료형이 int형으로 같으므로 비교할 수 있다는 문제가 있다.

    class Fruit{
        final Fruit APPLE = new Fruit("APPLE");
        final Fruit BANANA = new Fruit("BANANA");

        String name;
        
        public Fruit(String name) {
            this.name = name;
        }
    }

    class Company{
        final Company APPLE = new Company("APPLE");
        final Company SAMSUNG = new Company("SAMSUNG");

        String name;

        public Company(String name) {
            this.name = name;
        }
    }

그래서 위의 코드와 같이 상수를 해당 객체 타입의 생성자를 이용하여 분별해줄 수 있는 필드 값을 초기화하는 작업을 진행해주면 Company와 Fruit의 APPLE은 서로 다른 타입이기에 비교를 할 수 없게된다.

이와 똑같지는 않지만 이러한 개념으로 서로 분별력있는 상수를 가지는 클래스를 제공하는게 enum이다.

    enum Fruit{
        APPLE, BANANA;
    }

    enum Company{
        APPLE, SAMSUNG;
    }

enum으로 작성한 코드를 보면 훨씬 단순해진걸 확인할 수 있다.

정의하는 방법

    enum Fruit{
        APPLE(1000), BANANA(2000);

        private int price;
        
        Fruit(int price) {
            this.price = price;
        }
    }
  • 정의된 상수들은 대문자로 작성해야하며 각 상수는 콤마로 구분한다 또한 마지막 상수에는 세미콜론을 붙인다.

  • enum도 클래스이기에 생성자 및 필드를 가질 수 있다. 아래의 코드를 실행하면 APPLE(1000)에서 ()에 있는 1000이 price의 값으로 출력되는 것을 확인할 수 있다.

public static void main(String[] args) {
        System.out.printf("사과는 %d원입니다 " ,  Fruit.APPLE.price);
    }

enum이 제공하는 메소드 (values()와 valueOf())

enum의 메서드

메서드설명
T[] values()해당 enum 타입에 정의된 상수 배열을 반환한다.
Class getDeclaringClass()열거형의 객체를 반환한다.
String name()열거형 상수의 이름을 문자열로 반환한다.
int ordinal()열거형 상수가 정의된 순서를 반환한다.(0부터 시작)
T valueOf(Class enumType, String name)지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다.

values()

values() 메서드는 해당 enum이 가지고 있는 상수 배열을 리턴한다.

여기서 확인해야할 것은 상수가 enum 객체 타입으로 존재한다는 것이다.

아래의 코드를 보면 for문의 Fruit라는 enum객체를 사용한 것을 볼 수 있다.

enum Fruit{
      APPLE, BANANA;
  }

  public static void main(String[] args) {
      for (Fruit val : Fruit.values()) {
          System.out.println(val);
      }
  }

valuesOf()

valuesOf는 파라미터로 넘겨준 name값과 일치하는 상수가 있으면 해당 상수를 반환한다.

만약 없는 상수를 파라미터로 넘기는 경우 IllegalArgumentException이 발생한다.

사용법은 아래와 같이 두 가지가 있다.

    public static void main(String[] args) {
      System.out.println(Enum.valueOf(Fruit.class, "APPLE"));
      System.out.println(Fruit.valueOf("APPLE"));
  }

java.lang.Enum

java.lang 에 포함된 Enum 클래스는 모든 자바 열거형의 조상이다. 모든 열거형은 Enum 클래스를 상속받기 때문에 enum type은 별도의 상속을 받을 수 없다.
또한 enum에서 toString을 제외한 메서드들은 Enum클래스에 final로 선언되어 있으므로 자식 클래스에서 오버라이딩을 할 수 없다.

EnumSet

  • EnumSet은 enum을 보다쉽게 다루기위해 구현된 Set 구현체이다.
  • 같은 타입의 enum만을 값으로 가지는 Set이다.
  • null값을 추가할 수 없다.
  • Tread-safe하지 않다. 따라서 Collections.synchronizedMap을 이용하거나 동기화를 구현해야한다.

0개의 댓글