자바의 Enum

포모·2020년 12월 11일
0

JAVA API

목록 보기
3/5

1주차 프리코스 미션 <숫자 야구 게임>의 기능 목록 중 게임을 재시작할 것인지 종료할 것인지 입력 받는 기능을 구현해야 했습니다.

게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.
1

이때 입력받은 값을 검사하는 부분에서 1이나 2를 하드 코딩하는 것을 피하기 위해 final 변수로 선언해주었습니다.
그렇게 되면 종료/재시작을 검사하는 것에만 클래스 내 변수가 2개가 생성됩니다.
👉 final로 하드 코딩을 피하지만 내부 변수가 너무 많아진다는 점이 걸렸습니다.

그래서 처음에는 게임 시작과 종료에 대한 데이터를 가지고 있는 Game 클래스를 만들어주었습니다.

class Game {
	private static int START = 1;
	private static int END = 2;
}
  • 위와 같이 만드는 것은 클래스 내 선언하는 부분에서 네이밍이 겹칠 수 있고 불필요하게 상수가 많아지는 단점이 있다고 합니다.

  • 인터페이스로 관리하는 경우 : 위의 문제가 줄어들지만 여전히 IDE의 지원을 적극적으로 받을 수 없고 타입 안정성이 떨어진다고 합니다.


Enum이란?
열거형이라 불리며, 서로 연관된 상수들의 집합을 의미합니다.

  • Enum의 장점
    • 문자열과 비교해 IDE의 적극적인 지원을 받을 수 있습니다.
    • 허용 가능한 값들을 제한할 수 있습니다.
    • 리팩토링시 변경 범위가 최소화됩니다.


      C/C++은 Enumint 값이지만 Java의 Enum은 기능을 갖춘 클래스라고합니다.

클래스에 상수만으로 작성되어 있으면 반드시 class로 선언할 필요는 없고, enum을 선언하여 이 객체가 '상수의 집합'이라는 것을 명시적으로 나타낼 수 있습니다.


public enum GameType {
	START("1"), END("2");

	private String gameButton;

	GameType(String value) {
		this.gameButton = value;
	}

	public boolean equals(String input){
		return gameButton.equals(input);
	}
}
  1. GameType 클래스를 상수처럼 사용할 수 있습니다. : GameType.START
  2. Enum 클래스를 구현하는 경우 상수 값과 유일하게 하나의 인스턴스가 생성되어 사용됩니다. 👉 Singletone 형태로 사용되기 때문에 thread 환경에 유의
  3. 서로 관련 있는 상수 값들을 모아 enum으로 구현 👉 상수간의 관계를 파악할 수 있습니다.
  4. 상속을 지원하지 않습니다.

Enum API

values()

Enum 클래스가 가지고 있는 모든 상수 값을 배열의 형태로 리턴합니다.
즉, Enum 클래스가 가지고 있는 모든 인스턴스를 배열에 담아 반환합니다.

GameType[] types = GameType.values()
for (int i=0; i<types.length; i++) {
	System.out.println(types[i]);
}
// START, END

valueOf()

String을 파라미터로 받는데 인자로 들어온 String과 일치하는 상수 인스턴수가 존재하면 그 인스턴스를 반환합니다.

System.out.println(GameType.valueOf("START"));
// START

ordinal()

Enum 클래스 내부 상수들의 인덱스를 리턴하는 메소드입니다.
주의할 점은 gameButton 값과 별개인 Enum 인덱스임에 주의해야합니다.

GameType[] types = GameType.values();
for (int i = 0; i < types.length; i++) {
	System.out.println(types[i].ordinal());
}
// 0 1

Etc

  • name() : 호출된 값의 이름을 String으로 리턴한다.
  • compareTo(E o) : 이 Enum과 지정된 객체의 순서를 비교한다. 지정된 객체보다 작은 경우 음의 정수, 동일하면 0, 크면 양의 정수를 반환한다.
  • equals(Object other) : 지정된 객체가 이 Enum 정수와 같은 경우 true를 반환한다.

equals의 경우 객체를 비교하는 것에 유의해야합니다.

System.out.println(GameType.START.equals(GameType.START));
System.out.println(GameType.START.equals("START"));
System.out.println(GameType.START.equals("1"));

// true
// false
// false

Enum 활용하기

데이터 그룹화

관련되어 있지만 관련성을 표시하기 힘든 형태의 데이터를 한 곳에서 관리할 수 있는 것에 Enum이 적절하다고 합니다.

public enum payGroup {
	CASH("현금", <현금 결제 수단 리스트>)
	CARD("카드", <카드 결제 수단 리스트>)
	ETC(...)
	...
}

뿐만 아니라 상태(값)와 행위(메소드)를 한 곳에 관리하여 관련 로직을 쉽게 확인할 수 있습니다.

public enum CalculatorType {
    A(value -> value),
    B(value -> value * 10),
    C(value -> value * 3),
    D(value -> 0L);
    
    private Function<Long, Long> expression;
    
    CalculatorType(Fuction<Long, Long> expression) { this.expression = expression; }
    
    public long calculator(long value) { return expression.apply(value); }
}

서로 다른 계산식(A, B, C, D)을 사용할 때 다음과 같이 표현하여 Enum 내부에서 타입에 알맞게 표현식을 찾아주는 방식입니다.
(Lambda를 사용하여 중복될 수 있는 기능(calculator)를 하나로 만들어줍니다.)


🛴 마무리

글을 다 정리하고 보니 뭔가 부족한 느낌이 드네요...
제가 직접 Enum을 이것저것 활용해보고 추가적인 내용을 정리해보도록 하겠습니다! 💪

쉽게 설명하고 싶은데 생각보다 쉽지 않네여..😂


참고

0개의 댓글