[TIL] 20250106(2) Enum

Drumj·2025년 1월 6일
0

2025 TIL

목록 보기
7/11

Enum Type은 왜?

자바가 제공하는 열거형(Enum Type). 이놈은 왜 생긴걸까?

간단한 예제를 통해 알아보자.

public class DiscountService {

	public int discount(String grade, int price) {
		int discountPercent = 0;

		switch(grade) {
			case "BRONZE" -> discount = 10;
			case "SILVER" -> discount = 20;
			case "GOLD" -> discount = 30;
			default -> discount = 0;
		}
        
	return price * discountPercent / 100;
}

등급에 따라 할인율이 다른 경우가 있다. 이렇게 String을 직접 입력하게 되면
존재하지 않는 DIAMOND 등급이나 오타, 대소문자 구분에서 아주 취약하다.

내가 이 코드를 작성할 때는 브론즈,실버,골드 등급만을 생각했는데 다른 개발자가 해당 코드를 사용하려고 보니 discount(String grade, int price) "어라 등급은 그냥 String 을 사용하잖아?" 하고 discount("DIAMOND", 10000) 이라던가 discount("gold", 10000) 같은 식으로 코드를 작성할 수 있다.

흠.... 실무에서 다른 개발자가 실수하는걸 보고 상수를 사용하기로 했다!

public class Grade {
	public static final String BRONZE = "BRONZE";
    public static final String SILVER = "SILVER";
    public static final String GOLD = "GOLD";
}

//DiscountService.discount() 수정
public int discount(String grade, int price) {
	int discountPercent = 0;

	switch(grade) {
		case Grade.BRONZE -> discount = 10;
		case Grade.SILVER -> discount = 20;
		case Grade.GOLD -> discount = 30;
		default -> discount = 0;
	}    
return price * discountPercent / 100;

좋아! 이제는 실수하지 않겠지??

그러나... 이렇게 코드를 작성해도 여전히 discount(String grade, int price) 해당 메서드는 String 을 받고 있기 때문에 DIAMOND,gold 와 같은 값을 전달해서 오류가 발생할 수 있다... ㅠㅠ


그래서 Enum Type이 등장! 이넘등장!

public enum Grade {
	BRONZE, SILVER, GOLD
}

띠용? 이렇게만 작성하면 된다고? 이걸 내가 직접 작성을 한다면 아래의 코드와 비슷하다

public class Grade {
	public static final Grade BRONZE = new Grade();
    public static final Grade SILVER = new Grade();
    public static final Grade GOLD = new Grade();
    
    //private 생성자
    private Grade() {}
}

public static final Gradeprivate Grade() 부분을 작성해야하는 번거로움이 있는데
public enum 으로 생성하면 자바가 알아서 다 만들어준다. 그리고 아래와 같은 장점이 있다.

  • 타입 안정성 향상
  • 간결성 및 일관성
  • 확장성

또, 열거형을 사용하는 경우 static import 를 사용해서 코드를 더 읽기 쉽게 만들 수 있다.

import static Grade.*;

//DiscountService.discount() 수정
public int discount(Grade grade, int price) {
	int discountPercent = 0;

	switch(grade) {
		case BRONZE -> discount = 10;
		case SILVER -> discount = 20;
		case GOLD -> discount = 30;
		default -> discount = 0;
	}    
return price * discountPercent / 100;

import static 을 사용해서 코드를 수정해봤다. 아주 간결하고 한눈에 딱 들어온다!
여기서 또 하나의 장점은 enum 을 사용하면 switch() 를 사용할 수 있다는 것이다.

만약 public class Grade 이렇게 class로 구현했다면 switch() 를 사용하지 못하고 그냥 if 를 사용해야한다.. ㅠ


좀 더 알아보자

public enum Grade {
    BASIC(10), GOLD(20), DIAMOND(30);

    private final int discountPercent;

    Grade(int discountPercent) {
        this.discountPercent = discountPercent;
    }

    public int getDiscountPercent() {
        return discountPercent;
    }
}

Enum을 생성할 때 필요한 값을 추가로 넣었다. 이렇게 하면 등급과 할인율을 같이 관리할 수 있게 되는데 해당 값이 필요한 경우 grade.getDiscountPercent() 로 가져올 수 있다.

또한 enum 클래스에는 values() 라는 메서드가 있는데 이 메서드는 enum 클래스의 모든 값을 배열로 반환해준다.

public static Grade findByName(String name) {
	Grade[] values = values();
    for (Grade grade : values) { // {BAISC, GOLD, DIAMOND}
    	if (grade.name().equals(name)) {
        	return grade;
		}
	}
    return null;
}

그래서 위와 같이 String 값을 가지고 거기에 맞는 Grade 값을 가져올 수 있는 코드를 작성할 수 있는 것이다.

위의 Grade 클래스는 discountPercent 만 가지고 있지만 내가 원한다면 더 많은 필드를 가질 수도 있다.


참조

  • 김영한의 실전 자바 - 중급 1편

0개의 댓글