[Java] 열거형 (Enum) 알아보기

이상현·2023년 10월 16일
0

Java

목록 보기
7/21
post-thumbnail

본 게시글은 Java의 정석 - 남궁성 을 읽고 필기한 게시글 입니다.

열거형의 용도

열거형 (enumeration) 은 관련된 변수들의 그룹을 묶어서 타입을 정의해줌으로써 다양한 활용이 가능하도록 한다.

비슷한 성격의 변수들이 갖는 값에 의미를 부여해주고 싶을 때 enum이 유용하다.
대표적인 예시로는 HTTP 프로토콜의 상태 코드가 있다.

Ok -> 200
Accepted -> 202
NotFound -> 404
BadGateWay -> 502

자바 코드로 변환

public enum HTTPStatusCode {
    OK(200, "OK"),
    ACCEPTED(202, "Accepted"),
    NOT_FOUND(404, "Not Found"),
    BAD_GATEWAY(502, "Bad Gateway");
    
    private final int statusCode;
    private final String description;
    
    HttpStatusCode(int statusCode, String description) {
        this.statusCode = statusCode;
        this.description = description;
    }

	public int getStatusCode() {
        return this.statusCode;
    }

    public String getDescription() {
        return this.description;
    }
}

Enum 선언

enum 열거형이름 { 상수명1, 상수명2, ... }

사용법

enum Direction { EAST, SOUTH, WEST, NORTH }

int x, y;
Direction dir = Direction.EAST;
//..
switch (dir) {
	case EAST: x++;
    	break;
    case WEST: x--;
    	break;
    case SOUTH; y++;
    	break;
    case NORTH: y--;
    	break;
    }
}

연산자 == 도 사용 가능하다. (빠르다)

열거형의 메소드

  • values()
    열거형의 모든 상수를 배열에 담아 반환한다.

  • name()
    열거형 상수의 이름을 문자열로 반환한다.

  • int ordinal()
    열거형 상수가 정의된 순서를 반환한다.

  • int compareTo()
    비교대상이 같으면 0, 왼쪽이 크면 양수, 우측이 크면 음수 반환
    ex) dir.compareTo(Direction.WEST)

  • E valueOf(String name)
    name과 일치하는 열거형 상수를 찾아 반환한다.
    ex) Direction.valueOf("WEST") == Direction.WEST
    -> true

  • T valueOf(Class<T> enumType, String name)
    지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다.
    ex) Enum.valueOf(Direction.class, "EAST") == Direction.EAST
    -> true

열거형에 멤버 추가하기

열거형에 값을 추가할 수 있다. 열거형 상수의 이름 옆에 원하는 값을 괄호와 함께 적어주면 된다.
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }
그리고 추가한 값을 저장할 수 있는 인스턴스 변수와 생성자를 추가해야 한다. 이는 열거형 상수를 모두 정의해준 다음 작성하면 된다.

아래 예시 코드는 String값을 하나 더 추가했고, 값을 얻을 수 있는 getValue 도 추가했다.

enum Direction {
	EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
    
    // 인스턴스 변수
    private final int value; // 꼭 final일 필요는 없지면 상수이므로 붙혀준다.
    private final String symbol;
    
    // 생성자
    Direction(int value, String symbol) {
    	this.value = value;
        this.symbol = symbol;
    }
    
    public int getValue() { return value; }
    public String getSymbol() { return symbol; }
}

Enum 활용

enum Direction {
	EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
    
    private static final Direction[] DIR_ARR = Direction.values();
    private final int value; // 꼭 final일 필요는 없지면 상수이므로 붙혀준다.
    private final String symbol;
    
    Direction(int value, String symbol) {
    	this.value = value;
        this.symbol = symbol;
    }
    
    public int getValue() { return value; }
    public String getSymbol() { return symbol; }
    
    // num 만큼 90도 시계방향으로 회전한 방향을 반환한다.
    public Direction rotate(int num) {
    	num %= 4;
        if (num < 0) num += 4; // nun<0 일때 시계 반대 방향으로 회전
        return DIR_ARR[(value - 1 + num) % 4];
    }
    
    @Override
    public String toString() {
    	return name() + getSymbol();
    }
}

public static void main(String[] args) {
    for(Direction direction: Direction.values()) {
        System.out.println(direction.name() + " " + direction.getValue() + " " + direction.getSymbol());
    }
	Direction d1 = Direction.EAST;
    System.out.println(d1);
    System.out.println(d1.name());
    System.out.println(d1.rotate(2));
    System.out.println(Direction.WEST.rotate(-1).name());
}

출력 결과

EAST 1 >
SOUTH 2 V
WEST 3 <
NORTH 4 ^
EAST>
EAST
WEST<
SOUTH

Enum vs Class

Enum 으로 구현할 수 있는 것은 Class로도 구현이 가능하다.
어떤 상황에서 어떤 것을 사용하는것이 좋을까?

일단 Enum와 Class의 가장 큰 차이점은, Enum은 정해진 인스턴스를 프로그램 실행 전에 선언해 놓기 때문에 프로그램 실행 도중에 인스턴스를 추가할 수 없다는 것이다.

즉, Enum은 미리 선언해 둔 고정적인 값들만 사용 할 수 밖에 없다.

고로, 런타임시에 새로운 인스턴스를 만들 필요가 없다면 Enum, 만들고 싶다면 Class를 사용하는 것이 적당하다.

0개의 댓글