[Effective Java] item 35 : ordinal 메서드 대신 인스턴스 필드를 사용하라

DEINGVELOP·2023년 1월 28일
1

Effective Java

목록 보기
12/19

열거 타입 상수

열거 타입

: 일정 개수의 상수 값을 정의한 다음, 그 외의 값은 허용하지 않는 타입

  • ex) 사계절, 태양계의 행성, 카드게임의 카드 종류 등

열거 타입 상수

  • 대부분의 열거 타입 상수는 자연스럽게 하나의 정숫값에 대응된다.

  • 모든 열거 타입은 해당 상수가 그 열거타입에서 몇 번째 위치인지를 반환하는 ordinal이라는 메서드를 제공한다.

➡ 열거 타입 상수와 연결된 정숫값이 필요하면 ordinal 메서드를 이용하고 싶은 유혹에 빠진다.


ordinal을 잘못 사용하게 되면?

// ordinal을 잘못 사용한 예
public enum Ensemble {
	SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET;

	public int numberOfMusicians() { return ordinal() + 1; }
}
  • 동작은 하지만, 유지보수가 매우 끔찍해진다.

    • 상수 선언 순서를 바꾸는 순간, numberOfMusicians가 오작동하며, 이미 사용 중인 정수와 값이 같은 상수는 추가할 방법이 없다.
    • 예컨대 8중주(octet) 상수가 이미 있으니, 똑같이 8명이 연주하는 복4중주(double quartet)는 추가할 수도 없다.
  • 중간에 값을 비워둘 수 없다.

    • 연속되지 않는 값을 쓰기 위해서는, 쓰이지 않는 더미(dumy) 상수를 같이 추가해야만 한다.
    • 코드가 깔끔하지 못할 뿐 아니라,쓰이는 않는 값이 많아질수록 실용성이 떨어진다.

그렇다면, ordinal을 사용하지 않는 해결책은?

➡ 열거 타입 상수에 연결된 값은 ordinal 메서드로 얻지 말고, 인스턴스 필드에 저장하자.

public enum Ensemble {
	SOLO(1)DUET(2),
    TRI0(3),
    QUARTET(4),
    QUINTET(5),
    SEXTET(6),
    SEPTET(7),
    0CTET(8),
    DOUBLEJUARTET(8),
    N0NET(9), 
    DECTET(10), 
    TRIPLE_QUARTET(12);
    
	private final int numberOfMusicians;
    
	Ensemble(int size) { 
    	this.numberOfMusicians = size; 
    }
	
    public int numberOfMusicians() { 
    	return numberOfMusicians;
    } 
}

정리

  • Enum의 API 문서를 보면 ordinal에 대해 이렇게 쓰여 있다. “대부분 프로그래머는 이 메서드를 쓸 일이 없다. 이 메서드는 EnumSet과 EnumMap 같이 열거 타입 기반의 범용 자료구조에 쓸 목적으로 설계되었다.”

  • 따라서 이런 용도가 아니라면 ordinal 메서드는 절대 사용하지 말자.

0개의 댓글