Java/STUDY HALLE

[Java] enum

무토(MUTO) 2021. 1. 30. 03:43

0. 학습 목표

  • 자바의 열거형에 대해서 학습한다.
  1. enum 정의하는 방법
  2. enum이 제공하는 메소드 (values()와 valueOf())
  3. java.lang.Enum
  4. EnumSet

1. enum 정의하는 방법

  • 자바의 enum을 정의하는법은 일반적으로 클래스를 사용하는 방법과 다르지 않다.

1-1.기본형

package study.moon.test;

public enum Word {
    HELLO,
    WORLD

}
  • 말 그대로 데이터를 열거하는 방식으로 이루어져 있다. 마치 값이 채워진 배열과 같은 느낌이다.

1-2.데이터 표현형

package study.moon.test;

public enum Word {
    HELLO("HELLO"),
    WORLD("WORLD");

    String word;

    Word(String word) {
        this.word = word;
    }
}
  • enum 내부에 멤버변수를 생성하고, 생성자를 만들게 되면 열거형에 타입을 정해주어야한다.
package study.moon.test;

public enum Word {
    HELLO("HELLO"),
    WORLD("WORLD"),

    MY_NAME("MY_NAME",1),
    IS_MOON("IS_MOON",2);

    String word;
    int number;

    Word(String word) {
        this.word = word;
    }

    Word(String word, int number) {
        this.word = word;
        this.number = number;
    }
}
  • 다음과 같이 여러개의 생성자를 만들 수도 있으며, 여러개의 생성자를 만들 경우, 해당 타입을 골라서 채워넣을 수 있다.

2. enum이 제공하는 메소드

  • 한번 까보자 enum은 도대체 무엇을 하는 녀석일까?
  • 우리 스터디의 상징 바이트코드를 확인해보도록 한다.

  • 웃기는 녀석이다. 한 아무것도 한것이 없는데 안에서 어떤 일들이 일어났는지 살펴보자.

    1. 자기 멋대로 java.lang.Enum<Word>를 상속받고있다.
    2. 만들어둔 열거형은 static으로 전역이다.
    3. 거기에 final로 재할당까지 금지해두었다.
    4. 상속의 결과로 내 클래스 타입의 배열을 리턴하는 values()메소드,
    5. 그리고 valueOf(String) 메소드를 가진다.
  • 4번과 5번의 내용부터 먼저 살펴보자.

Main.java

package study.moon.test;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        System.out.println(Word.valueOf("WORLD"));
        System.out.println(Arrays.toString(Word.values()));
    }
}

Word.java

package study.moon.test;

public enum Word {
    OH,
    HELLO("HELLO"),
    WORLD("WORLD"),

    MY_NAME("MY_NAME",1),
    IS_MOON("IS_MOON",2);

    String word;
    int number;

    Word() {
    }

    Word(String word) {
        this.word = word;
    }

    Word(String word, int number) {
        this.word = word;
        this.number = number;
    }
}

  • 어떤 역할을 하는 메소드인지 유추가 가능하다. 추상화가 잘되어있어서 직관적이다.
  • values()는 내부의 열거형을 배열의 형태로 순서대로 return 한다. 따라서 다음과 같은 표현식도 가능하다.
package study.moon.test;

public class Main {

    public static void main(String[] args) {
        System.out.println(Word.values()[0]);
    }
}
  • valueOf(String name)은 enum 내부에 있는 열거중 해당 이름을 가진 것의 name필드를 가져온다.

3. java.lang.Enum

이녀석을 한번 살펴보자. 그래야 열거형에 대해서 조금 제대로 알 수 있을것 같다.

세가지를 구현을 해야한다고 적혀있다.
구현 내용을 살펴보면

  1. Constantable

    • constant를 보장받고
  2. Comparable

    • ordinal을 기준으로 정렬을 한다.

Main.java

package study.moon.test;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        System.out.println(Word.values()[0]);
        Word[] words = new Word[4];
        words[0] = Word.MY_NAME;
        words[1] = Word.HELLO;
        words[2] = Word.IS_MOON;
        words[3] = Word.WORLD;
        Arrays.sort(words);
        System.out.println(Arrays.toString(words));
    }
}

  1. Serializable
    • 직렬화도 적용된다.

핵심적인 멤버변수는 다음의 2개이다.

  1. String name
  • 선언되는 해당 enum 상수의 이름이다.
  1. int ordinlal
  • name과 같은 짝을 이루어 부여되는 int형 숫자이다. 0부터 시작한다.

아까 보았던 메소드도 한번 살펴보자.

그런데 아까 보았던 values()는 찾을수가 없다. 대체 어디서 온 메소드인 것일까?

4. EnumSet

이펙티브 자바의 저자 조슈아 블로크씨가 enum을 사용하면 더욱 효율적인 set과 map을 구현할 수 있다고 적어놓았다.

package study.moon.test;

import java.util.Arrays;
import java.util.EnumSet;

public class Main {

    public static void main(String[] args) {
        Word[] words = new Word[4];
        words[0] = Word.MY_NAME;
        words[1] = Word.HELLO;
        words[2] = Word.IS_MOON;
        words[3] = Word.WORLD;
        Arrays.sort(words);
        System.out.println(Arrays.toString(words));
        EnumSet<Word> enumSet1 = EnumSet.allOf(Word.class);
        EnumSet<Word> enumSet2 = EnumSet.of(words[0],words[1]);

        System.out.println(enumSet1);
        System.out.println(enumSet2);
    }
}
  • 다음과 같은 사용 방법을 가지는데 솔직히 EnumSet의 장점을 딱히 느끼진 못하겠다.

5. 느낀점

1) 하나의 비슷한 타입을 열거할 때 배열 말고 enum을 사용하여 이름지어 사용하는것이 괜찮을것 같다.

2) 각각의 타입이 모두 따로 정해져있고 정해져있는 값들끼리의 상호작용이 필요한 경우 고려해볼 방법인것 같다.

'Java > STUDY HALLE' 카테고리의 다른 글

[Java] 람다  (0) 2021.03.05
[Java] 쓰레드 Thread  (0) 2021.01.20
[Java] 예외처리  (0) 2021.01.15
[Java] 인터페이스  (0) 2021.01.08
[Java] 패키지  (0) 2020.12.29