본문 바로가기
JAVA

[java] Enum

by 햄과함께 2021. 1. 30.
320x100

열거타입이다.

타입을 가지기 때문에 타입도 같이 체크할 수 있다.

Enum 또한 클래스이기 때문에 멤버변수, 함수를 가질 수 있다.

 

정의하는 방법

public enum Week {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

 

enum 키워드를 사용하여 정의한다.

 

public enum Week {
    MONDAY("월요일"),
    TUESDAY("화요일"),
    WEDNESDAY("수요일"),
    THURSDAY("목요일"),
    FRIDAY("금요일"),
    SATURDAY("토요일"),
    SUNDAY("일요일");

    private String desc;

    Week(String desc) {
        this.desc = desc;
    }

    public String getDescription() {
        return this.desc;
    }
}

enum 또한 클래스이기 때문에 멤버변수와 함수를 정의할 수 있다.

 

Week week = Week.MONDAY;

 

하나의 타입처럼 사용할 수 있다.

 

// Week bytecode

public final enum Week extends java/lang/Enum {

  // compiled from: Week.java

  // access flags 0x4019
  public final static enum LWeek; MONDAY

  // access flags 0x4019
  public final static enum LWeek; TUESDAY

  // access flags 0x4019
  public final static enum LWeek; WEDNESDAY

  // access flags 0x4019
  public final static enum LWeek; THURSDAY

  // access flags 0x4019
  public final static enum LWeek; FRIDAY

  // access flags 0x4019
  public final static enum LWeek; SATURDAY

  // access flags 0x4019
  public final static enum LWeek; SUNDAY
  
  // ...
}

 

bytecode를 보면 java.lang.Enum 클래스를 상속하며 열거한 문자열들로 static enum 들을 정의하여 가지고 있다.


values(), valueOf()

values(), valueOf()는 enum class에서 제공해주는 함수다. 

둘 다 static 함수다.

 

values()

values() 함수는 enum class의 원소들을 명시한 순서대로 반환해준다.

반환값은  EnumType[]  이다.

Week[] values = Week.values();
for(Week value: values) {
  System.out.println(value);
}
// 출력
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

 

valueOf()

enum에 있는 요소들의 이름 문자열로 enum을 찾을 때 사용한다.

매칭되는 enum이 있다면 해당 enum을 가져온다.

만일 매칭되는 enum이 없다면 IllegalArgumentException 예외가 발생된다.

// MONDAY
System.out.println(Week.valueOf("MONDAY")); 

// java.lang.IllegalArgumentException: No enum constant Week.NOT_EXIST
System.out.println(Week.valueOf("NOT_EXIST"));

 

 valueOf(String name) 

위에서 사용한 함수는 파라미터로 name 문자열을 받는다.

 

 valueOf(Class<T> enumType, String name) 

추가로 enumType 클래스 타입을 name과 같이 파라미터로 받는 valueOf 함수도 제공한다.

 

// #1
Week week = Week.valueOf("MONDAY");
// #2
Week week2 = Week.valueOf(Week.class, "MONDAY");
// #3
Week week3 = Enum.valueOf(Week.class, "MONDAY");
// #4
Week week4 = Enum.valueOf("MONDAY"); // compile error
// #5
WeekDay weekDay = Week.valueOf(WeekDay.class, "MONDAY");

 

valueOf(enumtype, name) 함수는 java.lang.Enum에서 제공하는 함수로 Enum 클래스에서도 호출이 가능하다.

valueOf(name) 함수는 java.lang.Enum 에서 제공하는 함수가 아니기 때문에 Enum 클래스에서 호출할 수 없다.

// Week bytecode
// access flags 0x9
  public static valueOf(Ljava/lang/String;)LWeek;
   L0
    LINENUMBER 1 L0
    LDC LWeek;.class
    ALOAD 0
    INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
    CHECKCAST Week
    ARETURN
   L1
    LOCALVARIABLE name Ljava/lang/String; L0 L1 0
    MAXSTACK = 2
    MAXLOCALS = 1

 

bytecode를 보면 valueOf(name) 함수 내부에서 자신의 클래스타입을 enumtype으로 넘겨주어 java.lang.Enum.valueOf 함수를 호출하고 있다.


java.lang.Enum

java.lang 에서 제공해주는 클래스이다.

enum 키워드로 생성된 클래스들은 모두 해당 클래스들을 상속한다.

Serializable, Comparable 인터페이스를 implements 하고있다.

 

주된 함수

함수 설명
String name() enum 상수를 반환한다.
int ordinal() 상수가 열거된 순서(위치)를 반환한다. 0부터 시작.
Class getDeclaredClass() enum 타입을 반환한다.
boolean equals(Object) enum 타입과 상수가 동일한지 반환한다.
int compareTo(E) 자기 자신(this)의 ordinal 값과 파라미터로 받아온 객체의 ordinal 의 차이를 반환한다.

valueOf 함수는 위에서 설명했으므로 생략한다.

 

테스트

Week week = Week.WEDNESDAY;

String name = week.name(); // WEDNESDAY
int ordinal = week.ordinal(); // 2
Class clazz = week.getDeclaringClass(); // class Week
boolean equals1 = week.equals(Week.WEDNESDAY); // true
boolean equals2 = week.equals(Week.MONDAY); // false
boolean equals3 = week.equals(WeekDay.WEDNESDAY); // false
int compareTo1 = week.compareTo(Week.MONDAY); // 2
int compareTo2 = week.compareTo(Week.WEDNESDAY); // 0
int compareTo3 = week.compareTo(Week.FRIDAY); // -2

EnumSet

java.util 에서 제공해주는 클래스.

enum 타입을 요소로 하는 Set 구현체. (AbstractSet의 구현체이다.)

내부적으로 bit vector로 표현되기 때문에 성능이 좋다.

 

생성자

모든 생성자는 private이며 정적 팩토리 메서드로만 객체를 생성할 수 있다.

정적 팩토리 메서드는 생성자에 이름을 주어 의미있는 이름의 함수명을 줄 수 있다.

메서드명  설명
allOf(Class<E> elementType) 모든 enum 상수를 요소로 가지는 EnumSet 생성.
noneOf(Class<E> elementType) 빈 요소를 가지는 EnumSet 생성.
of(E e1, E e2, ...) e1, e2 ... 을 요소로 가지는 EnumSet 생성.
rangeOf(E from, E to) from ~ to 에 해당하는 Enum들을 요소로 가지는 EnumSet 생성. 순서는 ordinal 기준.

copyOf(Collection<E> c)
copyOf(EnumSet<E> s)

파라미터에 있는 요소들을 가지는 EnumSet 생성.

 

테스트

// [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
EnumSet set1 = EnumSet.allOf(Week.class);

// []
EnumSet set2 = EnumSet.noneOf(Week.class);

// [MONDAY, WEDNESDAY]
EnumSet set3 = EnumSet.of(Week.MONDAY, Week.WEDNESDAY);

// [MONDAY,TUESDAY,WEDNESDAY]
EnumSet set4 = EnumSet.range(Week.MONDAY, Week.WEDNESDAY);

// [SATURDAY, SUNDAY]
EnumSet set5 = EnumSet.complementOf(EnumSet.range(Week.MONDAY, Week.FRIDAY));

// [MONDAY, FRIDAY]
EnumSet set6 = EnumSet.copyOf(List.of(Week.MONDAY, Week.FRIDAY));
EnumSet set7 = EnumSet.copyOf(EnumSet.of(Week.MONDAY, Week.FRIDAY));

 


참고 

 

docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/Enum.html

docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/EnumSet.html

320x100

'JAVA' 카테고리의 다른 글

[Java] Annotation  (0) 2021.02.05
[Java] 멀티쓰레드  (0) 2021.01.23
[Java] 패키지  (0) 2020.12.27
[Java] 데이터, 변수, 배열  (0) 2020.12.27
[Java] JVM  (0) 2020.12.27

댓글