Enum이란, 서로 관련된 상수를 여러개 정의할 때 사용한다.
Enum(열거형)을 써야하는 이유는 다음과 같다.
- 허용되는 값들을 제한할 수 있다
- 리펙토링 시 변경범위가 최소화된다. 내용의 추가가 있어도 Enum 코드 외에 수정할 필요가 없다
- 자바의 Enum은 그외에 다양한 기능을 제공한다.
- 더 자세한 내용은 이펙티브자바에서 다루겠다
Enum 정의하는 방법
가장 기본적인 방법으로 아래와 같이 상수를 정의한다.
이제 여기서 각 상수에 가장 관련있는 값인 가격과 한국식 명을 추가하고 싶으면 생성자를 추가한다.
생성자에 변수말고도 각 상수마다 필요한 계산이 있다면 특정 상수에 함수를 관련 시키게 할 수 있다.
예를들면 삼성이 후원하는 매장에서 삼성노트북을 사면 할인을 해주는 그런 로직이 필요하다면 다음과 같이 만들면 된다.
추가적으로 가격은 매번 바뀔 수 있기 때문에 상수로 정의하지 않고 입력을 받으면 계산을 하는 식으로 바꾼다.
함수만 있어서는 유용하게 사용할 수 없다. 메소드를 추가하여 함수 expression을 사용해야 한다.
Enum이 제공하는 메소드
메서드 | 설명 |
T[] values() | 해당 enum 타입에 정의된 상수 배열을 반환 |
String name() | 열거형 상수의 이름을 문자열로 반환 |
int ordinal() | 열거형 상수가 정의된 순서를 반환(0부터 시작) |
T valueOf(Class<T> enumType, String name) | 지정된 열거형에서 name과 일치하는 열거형 상수를 반환 |
바이트 코드 분석
이번 Enum은 바이트 코드를 보면 새롭게 알 수 있는 점이 있다. 다음과 같이 컴파일러는 자동으로 추가해주는게 많다.
컴파일러가 values()/valueOf() 메소드 추가
java.lang.Enum
바이트코드를 보면 Enum클래스를 상속받는 데 어떤 기능을 사용할 수 있는지 살펴보겠다
String name()
private final String name;
public final String name() {
return name;
}
열거형 상수의 이름을 해당 열거형 선언에 선언된 대로 정확하게 반환한다.
개발자들은 toString()메서드를 사용해야 한다. 이 메서드는 주로 정확성이 중요한 특수한 상황에서 사용하도록 설계된 것이다.
public final int ordinal()
public final int ordinal() {
return ordinal;
}
대부분의 프로그래머는 이 메서드를 쓸 일이 없다. 이 메서드는 EnumSet과 EnumMap 같이 열거 타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다. 이 메서드를 의존하는 코드를 개발자가 작성하는 것은 안티패턴이다.
T valueOf(Class enumType, String name)
지정된 열거형에서 name과 일치하는 열거형을 반환하며 만약 존재하지 않는다면 IllegalArgumentExcpetion이 발생된다.
EnumSet
EnumSet의 상속 구조
특징
- enum 값만 포함할 수 있고, 모든 값은 동일한 enum 에 속해야 함
- null 값을 추가하는 것을 허용하지 않으며, 시도하면 NullPointerException 이 발생
- thread 로부터 안전하지 않으므로, 필요한 경우 외부에서 동기화해야 함
- HashSet 보다 훨씬 빠른 고성능 구현체
- iterator 를 사용한 복제에서, fail-safe 하므로 컬렉션을 반복하면서 컬렉션이 수정될 때 ConcurrentModificationException 이 발생하지 않음
- Enumset 의 모든 메서드는 산술 비트 연산자를 이용하여 구현
사용 이유
- EnumSet과 HashSet을 비교했을 때 보통 전자가 빠른데, 값을 예측 가능한 순서로 저장하여, 각각의 계산에 단 하나의 비트만 검사하면 되기 때문이다.
- HashSet과는 달리 정확한 버킷을 찾기 위해 해시코드를 연산할 필요가 없으며, 또한 비트 벡터의 특성으로 인해 EnumSet은 매우 작고 효율적임(메모리 덜 사용)
사용 예제
실행결과
> Task :EnumSetExample.main()
set1 = [BANANA, ORANGE]
set2 = [APPLE]
set3 = [APPLE, BANANA, ORANGE]
set4 = [APPLE, BANANA, ORANGE]
- of(E e1, E e2) : 지정된 요소를 포함하는 열거형 집합을 처음에 생성
- complementOf(EnumSet<E> s) : 지정된 열거형 집합과 동일한 요소 유형으로 열거형 집합을 생성하며, 처음에는 지정된 집합에 포함되지 않은 이 유형의 모든 요소를 포함
- allOf(Class<E> emementType) : 지정된 요소 유형의 모든 요소를 포함는 열거형 집합을 만든다.
- range(E from, E to) : 지정된 두 엔드포인트에 정의된 범위의 모든 요소를 포함하는 열거형 집합을 처음에 생성
참고
https://wisdom-and-record.tistory.com/52
https://www.geeksforgeeks.org/enumset-class-java/
'공부방 > JAVA' 카테고리의 다른 글
Annotation 커스텀 하기 - 백기선 자바라이브스터디 (0) | 2023.09.30 |
---|---|
자바 리플렉션(Reflaction) (0) | 2023.09.28 |
멀티스레드와 동기화 문제 - 백기선 자바라이브스터디 (0) | 2023.09.20 |
예외처리 , 그거 어떻게 하는건데 (0) | 2023.09.12 |
자바 인터페이스 - 백기선 자바라이브스터디 (0) | 2023.09.07 |