glenn-syj / more-effective-java

이펙티브 자바를 읽으며 자바를 더 효율적으로 공부합니다
4 stars 5 forks source link

[MEJ-005] enum에 대한 조사 #106

Closed clare-u closed 6 months ago

clare-u commented 7 months ago

Based on: #100 by @FickleBoBo


다루려다가 제외하신 enum에 대해 저도 이해가 부족한 상태이기에 추가적으로 조사한 내용을 공유합니다.

Enum은 열거형이라고도 불리며, 여러 개의 상수 값을 갖는 특별한 데이터 타입입니다. Enum을 사용해서 코드의 가독성을 높임은 물론, 값의 범위를 제한하여 컴파일 때는 발견할 수 없는 논리적 오류를 줄일 수 있습니다.

사계절을 나타내는 Season이라는 Enum을 생성하기 위해, 일반적인 상수로 정의된 코드부터 발전시켜 나가보겠습니다.

public static final int SPRING = 0;
public static final int SUMMER = 1;
public static final int FALL = 2;
public static final int WINTER = 3;

이 선언은 여러 가지 문제점이 있지만 대표적으로 정수형이기에 0~3 이외의 값도 할당이 가능하고, 각 정수가 무엇을 의미하는지 확인이 필요하기에 가독성도 좋지 않습니다.

이 코드를 Enum을 사용하여 발전시켜보겠습니다.

먼저 enum 타입을 정의합니다. enum 키워드를 통해 선언하며, 각 상수 값은 콤마로 구분합니다.

public enum Season {
    SPRING, SUMMER, FALL, WINTER
}

enum을 사용하면, Season 변수에는 오직 SPRING, SUMMER, FALL, WINTER 중 하나의 값만 할당될 수 있습니다. 이를 통해 값의 범위를 제한하고, 코드의 안전성을 높일 수 있습니다.

Season currentSeason = Season.SPRING;
// 열거타입 변수 = 열거타입.열거상수;

이처럼 enum 상수는 대문자로 작성하는 것이 일반적인 관례입니다.

아래와 같이 Enum은 메서드와 필드도 가질 수 있으며, 생성자를 통해 초기화도 가능합니다.

public enum Season {
    SPRING("봄"),
    SUMMER("여름"),
    FALL("가을"),
    WINTER("겨울");

    private String koreanName;

    Season(String koreanName) {
        this.koreanName = koreanName;
    }

    public String getKoreanName() {
        return koreanName;
    }
}

참고 자료: https://gsbang.tistory.com/entry/JAVA-enum-%EC%97%B4%EA%B1%B0%ED%98%95

또한 enum 타입은 특수한 클래스여서 기본형이 아닌 참조형 타입으로 분류되어, enum 상수값은 힙 영역에 저장되게 됩니다. 그래서 다음과 같이 == 연산 결과는 true가 반환됩니다..

Season currentSeason = null; // 참조 타입이기 때문에 null도 저장 가능
currentSeason = Season.SPRING;

// 주소값 비교
System.out.println(currentSeason == Season.SPRING); // true

참고 자료: https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%97%B4%EA%B1%B0%ED%98%95Enum-%ED%83%80%EC%9E%85-%EB%AC%B8%EB%B2%95-%ED%99%9C%EC%9A%A9-%EC%A0%95%EB%A6%AC#enum_%EC%83%81%EC%88%98

FickleBoBo commented 7 months ago

Enum에 대해서 정말 자세히 조사해주셔서 앞으로 학습에 많은 도움이 될 것 같습니다. 단순히 Enum은 열거형 이정도로만 아주 단순하게 알고 막상 한번도 써본 적이 없었는데 활용 방안에 대해 충분히 고민해볼만한 내용인 것 같습니다. class, interface와 마찬가지로 소스 파일 생성 단계에서 enum을 선택할 수 있는 것을 여태 봤었는데, 설명해주신 내용처럼 코드의 가독성적인 측면과 class와 비슷해보이지만 기능적 제한을 통해 코드의 안전성을 높일 수 있을 것 같습니다. 올려주신 참고자료를 통해 다양한 기능적 이점들도 볼 수 있어서 좋았습니다.