0. 학습 목표
- 자바의 열거형에 대해서 학습한다.
- enum 정의하는 방법
- enum이 제공하는 메소드 (values()와 valueOf())
- java.lang.Enum
- 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은 도대체 무엇을 하는 녀석일까?
- 우리 스터디의 상징 바이트코드를 확인해보도록 한다.
웃기는 녀석이다. 한 아무것도 한것이 없는데 안에서 어떤 일들이 일어났는지 살펴보자.
- 자기 멋대로 java.lang.Enum<
Word
>를 상속받고있다. - 만들어둔 열거형은 static으로 전역이다.
- 거기에 final로 재할당까지 금지해두었다.
- 상속의 결과로 내 클래스 타입의 배열을 리턴하는 values()메소드,
- 그리고 valueOf(String) 메소드를 가진다.
- 자기 멋대로 java.lang.Enum<
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
이녀석을 한번 살펴보자. 그래야 열거형에 대해서 조금 제대로 알 수 있을것 같다.
세가지를 구현을 해야한다고 적혀있다.
구현 내용을 살펴보면
Constantable
- constant를 보장받고
- constant를 보장받고
Comparable
- ordinal을 기준으로 정렬을 한다.
- 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));
}
}
- Serializable
- 직렬화도 적용된다.
- 직렬화도 적용된다.
핵심적인 멤버변수는 다음의 2개이다.
- String name
- 선언되는 해당 enum 상수의 이름이다.
- 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 |