본문 바로가기
Language/Java

자바 11주차 : Enum

by CleanCoder 2021. 3. 5.

 

목표

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

학습할 것 (필수)

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

 

 

1. enum 정의하는 방법

 

  • enum 키워드를 이용하여 정의한다.
  • 열거형 필드의 이름은 상수이기 때문에 대문자로 표기한다.
  • 기본적으로 0부터 시작하는 정숫값이 연속적으로 부여된다.
/*
enum 열거형이름 { 상수명1, 상수명2, ...}
*/
enum Day { // 0부터 연속적인 정수값 부여
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY; 
}
  • Hamburger라는 enum을 정의한 후
  • EnumTest 클래스에서 init() 메소드 호출 시 열거형 인스턴스 변수에 Hamburger.BIGMAC 대입
enum Hamburger {
    BIGMAC, SHANGHI, MACCHICKEN;
}

public class EnumTest {
    public static void main(String[] args) {
        Hamburger hamburger = Hamburger.BIGMAC;
        System.out.println(hamburger + "버거 입니다.");

    }
}
  • 모든 enum은 클래스를 사용해서 내부적으로 정의가 된다.
  • 실제로 컴파일까지 한 후 바이트 코드를 분석해보면 아래와 같이 출력된다.
// 내부적으로 위에서 작성한 enum은 아래와 같이 바뀐다.
class Hamburger
{
     public static final Hamburger BIGMAC = new Hamburger();
     public static final Hamburger SHANGHI = new Hamburger();
     public static final Hamburger MACCHICKEN = new Hamburger();
}
  • 열거형 상수의 비교에는 ==와 compartTo() 사용가능 (등가비교연산자 가능)
  • =, >, >=, <, <=, <> 같은 비교연산자는 사용할 수 없음(컴파일 에러)
if (NORMAR.BIGMAC > MACALL.BIGMAC) { // 열거형 상수에는 비교연산자 사용불가
    System.out.println("이렇게 사용하면 컴파일에러가 납니다.");
}

비교 연산자를 쓸 수 없는 이유

 

바이트코드를 분석해보면 알겠지만 enum은 클래스이다. 클래스에서 비교연산자를 쓸 수 있었는지 생각해보면 객체와 객체는 서로 비교연산자를 쓸 수 없기 때문에 enum에서 지원하지 않는 것이다.

 

 

2. java.lang.Enum

메소드 설명
Class getDeclaringClass() 열거형의 Class객체를 반환
String name() 열거형 상수의 이름을 문자열로 반환
int ordinal() 열거형 상수가 정의된 순서를 반환(0부터 시작)
T valueOf(Class enumType, String name) 지정된 열거형에서 name과 일치하는 열거형 상수를 반환
compareTo(E o) 지정된 객체보다 작은 경우 음의 정수, 동일한 경우 0, 크면 양의정수를 반환

그 밖에 clone(), equals(), finalize(), toString(), hashCode() 메소드들도 있는데 이는 Object 클래스로부터 상속받은 메소드이기 때문에 따로 언급하지 않는다.

 

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

위에서 본 java.lang.Enum 즉 열거형의 조상 클래스에선 values(), valueOf() 메소드에 대한 내용을 자세히 찾아볼 수 없다. 그 이유는 컴파일러가 자동으로 추가해 주는 메소드이기 때문이다.

 

예제를 통해 각 메소드별 결과값과 실제로 컴파일러가 자동으로 어떻게 추가해 주는지 내부적으로 확인해보자

 

컴파일까지 실행한 후 바이트코드를 분석해보면 static으로 선언되어 있는 메소드 2개를 발견할 수 있다. 이로써 values(), valueOf() 메소드는 컴파일러가 자동으로 추가해 주는다는 사실을 직접 확인할 수 있다.

 

enum Hamburger {
    BIGMAC, SHANGHI, MACCHICKEN;
}

public class EnumTest {
    public static void main(String[] args) {
        Hamburger hamburger = Hamburger.valueOf("MACCHICKEN");
        System.out.println(hamburger + " 버거 입니다.");
    }
}
MACCHICKEN 버거 입니다.
enum Hamburger {
    BIGMAC, SHANGHI, MACCHICKEN;
}

public class EnumTest {

    public static void main(String[] args) {
        Hamburger[] hamburger = Hamburger.values();
        System.out.println("현재 저희 매장에 있는 버거는");
        for (Hamburger burgers : hamburger) {
            System.out.println(burgers + " 버거가 있습니다.");
        }
    }
}
현재 저희 매장에 있는 버거는
BIGMAC 버거가 있습니다.
SHANGHI 버거가 있습니다.
MACCHICKEN 버거가 있습니다.

열거형의 생성자는 묵시적으로 private 이므로, 외부에서 객체생성이 불가능하다.

 

 

4. EnumSet

 

Set

Set은 객체(데이터)를 중복해서 저장할 수 없다. 또한 저장된 객체(데이터)를 인덱스로 관리하지 않기 때문에 저장 순서가 보장되지 않는다 Set 컬렉션을 구현하는 대표적인 클래스들은 HashSet, TreeSet, LinkedHashSet 등이 있다. 주로 공통적으로 사용하는 메소드들은 add, iterator, size, remove, clear 들이 있다.

 

EnumSet

Set 인터페이스를 기반으로 하면서 Enumeration type을 사용하는 방법이다

 

메소드 설명
allOf(Class elementType) 인자로 들어온 enum을 그대로 enum set 생성
complementOf(EnumSet s) 인자로 들어온 enum set에서 없는 요소들로 만 다시 enum set 생성
of(E e1, E e2, E e3, E e4, E e5) 초기값으로 지정한 값들로 enum set 생성
range(E fro,, E to) 처음과 끝을 입력하면 그 사이에 있는 값들로 enum set 생성

 

import java.util.EnumSet;

enum Gfg { CODE, LEARN, CONTRIBUTE, QUIZ, MCQ };

public class EnumSetExample {
    public static void main(String[] args) {
        // Creating a set
        EnumSet<Gfg> set1, set2, set3, set4;

        // Adding elements
        set1 = EnumSet.of(Gfg.QUIZ, Gfg.CONTRIBUTE, Gfg.LEARN, Gfg.CODE); // 일일이 입력하는거 같음
        set2 = EnumSet.complementOf(set1); // 인자로 들어온 enumset에서 누락된값만 집어넣나???
        set3 = EnumSet.allOf(Gfg.class); // 전체를 다 집어넣음
        set4 = EnumSet.range(Gfg.CODE, Gfg.CONTRIBUTE); //시작범위, 끝범위 입력하면 그 사이에 값 대입

        System.out.println("Set 1: " + set1);
        System.out.println("Set 2: " + set2);
        System.out.println("Set 3: " + set3);
        System.out.println("Set 4: " + set4);
    }
}
Set 1: [CODE, LEARN, CONTRIBUTE, QUIZ]
Set 2: [MCQ]
Set 3: [CODE, LEARN, CONTRIBUTE, QUIZ, MCQ]
Set 4: [CODE, LEARN, CONTRIBUTE]

 

'Language > Java' 카테고리의 다른 글

자바 12주차 : 애노테이션  (0) 2021.03.05
자바 10주차 : 멀티쓰레드 프로그래밍  (0) 2021.03.05
자바 9주차 : 예외 처리  (0) 2021.02.14
JAVA 8주차 : 인터페이스  (0) 2021.02.14
JAVA 7주차 : 패키지  (0) 2021.02.14

댓글