열거형 Enum

Tina Jeong·2021년 3월 5일
0

Re-자바

목록 보기
15/16

enum

enum은 열거enumeration의 약자이다. 동서남북, 요일 등을 표시할 때 쓰일 수 있다. 즉, 하나의 범주로 묶일 수 있는, 너무 많지 않은 상수의 목록을 enum을 이용하면 편리하다. 해당 상수의 목록은 compile 타임에 정해질 수 있는 것이어야 한다. 즉, 정해진 사이즈를 가지며 new를 이용한 명시적인 instantiation은 불가하다.

또, enum은 자바 언어의 키워드이다. enum은 암시적으로 java.lang.Enum을 상속 받으며, 특별한 타입의 자바 클래스라고 할 수 있다. Enum 클래스의 기능을 이용할 수 있음과 동시에, enum type은 extends 키워드를 통해 다른 타입을 상속 받을 수 없다. 자바는 다중 상속을 허용하지 않았기 때문이다.

enum 정의하는 방법

class 키워드 대신 enum 키워드와 함께 정의할 수 있다. enum과 final, abstract 키워드를 함께 사용하면 컴파일 에러가 난다. enum은 암시적으로 final을 의미하기 때문이고, enum은 상속받거나 상속 할 수 없기 때문이다.

enum Direction {
        EAST, WEST, SOUTH, NORTH
}

enum은 optional한 enum body를 가질 수 있으며, 이런 경우 마지막 enum constant에는 세미콜론을 붙여서 표시한다.

enum Direction {
        EAST , WEST, SOUTH, NORTH;
        public EnumSet<Direction> homeToSchool() {
            return  EnumSet.of(Direction.NORTH,Direction.EAST,Direction.WEST);
        }
}

java.lang.Enum

Enum 클래스는 Serializable, Comparable, Constable 인터페이스를 상속받고, c에서는 enum을 단순히 integer replaceable representation으로 처리하지만, 자바에서는 기본적인 enum의 기능과 더불어 특별한 메소드들을 제공한다.

enum이 제공하는 메소드

Direction south = Direction.SOUTH;
System.out.println(south.ordinal()); //2
System.out.println(south.name()); //SOUTH

Direction west = Direction.valueOf("WEST");
System.out.println(west.name()); // WEST

for(Direction direction : Direction.values()) {
      System.out.println(direction.name());
};
  • int ordinal()
    특정 enum 상수의 index 값을 반환한다.

  • String name()
    enum 변수의의 이름을 반환한다.

  • static T valueOf("상수이름")
    상수 이름을 인자로 받아 해당 enum에 정확히 일치하는 enum 상수가 있는 경우 반환한다. 만약 인자에 공백이 들어가는등 enum이름이 정확하지 않으면 IllegalArgumentException이 발생한다.

  • static T[] values()
    enum의 상수를 배열 형태로 반환해준다. 보통 enum을 순회하는 용도로 사용한다.

java.util.EnumSet

자바 collection의 set을 상속받아 enum 타입이 set의 인터페이스를 이용할 수 있으며, 내부적으로 비트연산을 이용해 처리속도가 아주 빠르다. 또, 정적인 타입을 콜렉션의 맥락에서 동적으로 활용할 수 있는 것이 장점인듯.

EnumSet을 사용할 때는 해당 set이 하나의 enum 타입으로만 이루어져야 한다.of 메소드 시리즈를 이용해 EnumSet을 생성할 수 있으며, allOf()는 해당 enum 타입의 모든 enum을 넣어만든 EnumSet을, noneOf() 해당 enum 타입인 빈 set을 만든다. 최대 5개까지 인자에 넣어 enum 타입의 일부 상수로 set을 구성할 수도 있다. [시작,끝]을 포함해 특정 범위의 set을 만들 수도 있다.

EnumSet es = EnumSet.allOf(Direction.class);
EnumSet es2 = EnumSet.noneOf(Direction.class);
EnumSet es3 = EnumSet.of(Direction.EAST,Direction.NORTH);
EnumSet es4 = EnumSet.range(Direction.SOUTH,Direction.NORTH);

필요한 경우 add 함수로 enum상수를 추가할 수 있다. EnumSet에 null을 추가하면 NullPointerException이 발생하므로 추가할 수 없다.

es.add(Direction.EAST);

이 부분에서 주의할 점은 EnumSet은 자동으로 동기화되지 않는다는 사실. 다중스레드 환경에서 특정 스레드가 EnumSet을 수정할 경우 다음과 같이 명시적인 동기화 처리를 해주어야 한다.

 Set<MyEnum> s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));

제목에 최대한 한글 표기를 사용하려고 했지만..enum은 이넘이라쓰기도..열거형이라 쓰기도 어색하군.

참고
https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/lang/Enum.html
https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/EnumSet.html
The Java® Language Specification, Java SE 15 Edition
https://www.baeldung.com/java-enumset
https://www.geeksforgeeks.org/enum-customized-value-java/

계속해서 문서를 업데이트하고 있습니다. 언제든지 댓글피드백 남겨주세요. 😉

profile
Keep exploring, 계속 탐색하세요.

0개의 댓글