Java | enum(열거형)이란? enum 활용 예시

박예선·2023년 7월 11일
0

Java

목록 보기
6/6
post-thumbnail

강의를 들으며 실습하는데 enum을 통해 특정 타입을 만들어서 사용하거나
에러코드를 생성해서 사용하는 것을 보며
무작정 따라 쓰기보단 한번 더 알아볼 필요성을 느껴 정리해보았다.
마지막에는 실습 때 사용했던 예제코드로 다시 한번 정리함!

+) 난 enum을 몇번 사용해보고 알아본 경우라 잘 이해했지만,
enum을 처음 접하거나 이해가 잘 되지 않는 경우에는
맨 아래에 링크로 첨부해둔 생활코딩 유튜브 강력 추천!
4개의 짧은 영상으로 이루어져 있는데 보고나니 개념이 더 잘 잡혔다.

enum이란?

enum은 연관된 값들, 특히 변하지 않는 상수를 다룰 때 사용한다.

enum은 일반적인 클래스로도 표현이 가능하지만 일반클래스로 표현 시의 단점들을 보완하기 위해 java가 enum이라는 문법을 지원하게 되었다.

enum을 사용하는 이유
- 코드가 단순해진다.
- 인스턴스 생성과 상속을 방지한다.
- 키워드 enum을 사용하기 때문에 구현의도가 열거임을 분명하게 나타낸다.

추가적으로, 공식문서에서는 열거형 유형을 집합 유형으로 사용하거나 맵의 키 유형으로 사용할 경우 특수하고 효율적인 집합 및 맵 구현을 사용할 수 있습니다. 라고 한다.

//  enum을 일반 클래스로 표시하자면 아래의 주석친 코드와 일치한다.
//  enum을 사용하는 경우와 확연히 비교된다.
//  class Color{
//	  public static final Color GREEN = new Color();
//    public static final Color YELLOW = new Color();
//    public static final Color RED = new Color();
//  }

// enum을 사용하는 경우
enum Color{
	GREEN, YELLOW, RED;
}

// enum을 사용하면 이렇게 가독성있게 상수를 표현할 수 있다.
public class Main{
	public static void main(String[] args){
    
    	Color type = Color.GREEN;
        
        switch(type){
        	case GREEN:
            	System.out.println("green");
                break;
        	case YELLOW:
            	System.out.println("yellow");
                break;
        	case RED:
            	System.out.println("red");
                break;
            // 이미 위의 type 변수를 선언할 때
            // Color 타입이라는 것을 알려줬기 때문에
            // Color.GREEN, Color.YELLOW 이런 식으로 사용하지 않아도 된다.
        }
    }
}

enum의 활용

enum은 클래스라서 생성자를 가질 수도 있다.
또한 변수, 메소드도 가질 수 있다.

변수, 생성자의 활용

enum Color{
	GREEN("Go"), YELLOW("Warn"), RED("Stop"); 
//  public static final Color GREEN = new Color("Go"); 와 같다고 생각하면 된다.
    
    public String signal; 	// 변수
    
    Color(String signal){ 	// 생성자
    	System.out.println("Constructor " + this);
        this.signal = signal;
    }
}

public class Main{
	public static void main(String[] args){
    
    	Color type = Color.GREEN;
        
        switch(type){
        	case GREEN:
            	System.out.println("signal is " + Color.GREEN.signal);
                break;
        	case YELLOW:
            	System.out.println("signal is " + Color.YELLOW.signal);
                break;
        	case RED:
            	System.out.println("signal is " + Color.RED.signal);
                break;
        }
    }
}
// 메인클래스의 실행결과
//
// Constructor GREEN   // 1번
// Constructor YELLOW  // 2번
// Constructor RED	   // 3번
// signal is Go        // 4번
//
// 1~3번이 나오는 이유 : enum을 일반클래스로 표현했을 때
// public static final Color GREEN = new Color();
// 로 표현되기 때문에 하나의 타입 당 하나의 생성자가 호출되어 나오게 된다.
//
// 4번이 나오는 이유 : switch문을 통해 나오게 된다.

메소드의 활용

enum Color{
	GREEN("Go"), YELLOW("Warn"), RED("Stop");
    
    private String signal;
    // 메소드가 있으니 private으로 변경해 값을 변경하지 못하도록 했다.
    
    public String getSignal(){
    	return this.signal;
    }
}

public class Main{
	public static void main(String[] args){
    
    	Color type = Color.GREEN;
        
        switch(type){
        	case GREEN:
            	System.out.println("signal is " + Color.GREEN.getSignal());
                break;
        	case YELLOW:
            	System.out.println("signal is " + Color.YELLOW.getSignal());
                break;
        	case RED:
            	System.out.println("signal is " + Color.RED.getSignal());
                break;
        }
    }
}
// 메인클래스 실행결과
//
// signal is Go
//
// getSignal 이라는 메소드를 통해 변수를 가져왔다.

이렇게 사용하게 되면 enum이 단순히 상수로서의 기능만 하는 것이 아니라
어떠한 값을 갖게 할 수 있다.

=> 에러코드로서 enum을 활용하는 경우를 보면 더 이해가 쉽다.


enum을 활용해 에러코드 만들기

실제 실습에서 사용했던 코드를 간단하게 변형시켜 예제로 만들어보았다.

// ErrorCode.java - 에러코드를 정의한 enum 파일
// lombok 라이브러리를 사용해 간단하게 게터 함수와 생성자를 설정했다.
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter 
@AllArgsConstructor 
public enum ErrorCode {
    USER_NOT_FOUND("사용자가 없습니다."),
    DATA_NOT_FOUND("정보가 없습니다."),
    ALREADY_EXPIRED("유효기간이 지났습니다.")
    ;

    private final String description;
}


// CustomException.java - 에러코드 enum을 활용할 커스텀Exception파일
import com.example.type.ErrorCode;
import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class CustomException extends RuntimeException {
    private ErrorCode errorCode;
    private String errorMessage;

    public CustomException(ErrorCode errorCode) {
        this.errorCode = errorCode;
        this.errorMessage = errorCode.getDescription();
        // errorCode의 description 변수를 가져온다.
    }
}

이런 식으로 ErrorCode enum파일과 CustomException 파일을 설정하면,
실제 서비스를 구현하는 파일에서 만약 에러를 뱉어내야하는 상황이 생긴다면

서비스 구현 코드코드코드코드코드코드
	.orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND));

이런 식으로 예외가 발생했을 때 enum을 넘겨주면 우리가 원하는 에러메세지가 표시된다.
(USER_NOT_FOUND의 경우엔 "사용자가 없습니다.")


enum은 에러메세지 말고도 특정한 상수로서의 타입을 사용해야 하는 경우에 적절히 사용하면
가독성이 좋아지고 구현의도가 명확해 런타임에러의 가능성을 줄여준다.
잘 이해하고 사용하면 코드의 퀄리티를 훨씬 높일 수 있는 문법인 것 같다!


궁금한 점이나 잘못된 점은 댓글 부탁드립니다 :)
도움되셨으면 좋아요 눌러주세요!❤️


Reference

자바 공식문서
유튜브 - 생활코딩

profile
개발 좋아 lynn08082@gmail.com

0개의 댓글