티스토리 뷰

Java

Java Enum

woo'^'chang 2022. 6. 16. 21:48

시작하기

배경

Enum 활용해보자!

위 이미지는 IntelliJ 프로젝트에서 새로운 자바 클래스를 생성할 때 확인할 수 있는 창이다.

 

평소 자바 프로젝트를 진행하면서 ClassInterface는 자주 생성해서 사용했지만 Enum은 유독 사용하지 않았다. Enum이 개념적으로 무엇인지는 알고 있지만, 확실하게 정리가 되지 않았기에 사용을 꺼렸던 것 같다.

 

Enum 개념을 확실히 정리하고 장점을 살려 코드를 작성해보고자 한다.

불편함

상수란? 변하지 않거나 일정한 값을 가진 수나 양을 의미

 

자바에서는 모든 것이 클래스이므로 상수를 관리하기 위한 별도의 클래스를 정의할 수 있다.

public final class MyConstant {
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int THREE = 3;
}

final예약어를 사용하여 초기화 이후 변하지 않음을 나타내고 static예약어를 사용하여 해당 클래스의 인스턴스 생성없이 사용할 수 있도록 정의한다.

public class Main {
    public static void main(String args[]) {
        System.out.println(MyConstant.ONE);
    }
}

// 출력결과
1

Class를 통해 상수를 관리하기에 꽤 괜찮은 방법이라는 생각이 들 수 있다.하지만 상수를 위와 같은 방법으로 다루기에는 불편함이 존재한다.

타입 안전성이 보장되지 않는다.

수학 문제에서 난이도가 BASIC 문제와 HARD 문제가 존재하고 각각 난이도에서도 레벨이 존재할 때 다음과 같이 표현할 수 있다.

다른 난이도 문제임에도 레벨에 의해 같은 값을 가질 수 있다.

 

상수로 이를 관리하게 된다면 컴파일러는 2개를 같은 값으로 인식하기에 타입적인 안정성을 가지기 힘든 문제가 발생한다.

 

BASIC_LEVEL_ONE이 들어가야 할 곳에 HARD_LEVEL_ONE이 들어가도 정상적으로 컴파일이 수행된다는 의미이다.

 

이는 표현력 문제까지 연결되는 문제이다.

프로그램 관리도 불편하다.

열거형으로 상수를 관리하는 방법은 해당 값이 클라이언트에게 그대로 전해지기 때문에 변경이 발생하면 다시 컴파일해줘야 한다. 다시 컴파일해주지 않는다면 변경된 점이 반영되지 않은 이전의 프로그램으로 동작하게 된다.

Java Enum

등장

열거형 타입의 필요성을 느끼게 되었고 자바 1.5버전부터 새로 추가되었다.

 

자바에서는 Class이기에 얻을 수 있는 별도의 장점이 존재한다.

특징

이름 공간이 존재한다.

다음과 같이 Basic, Hard를 정의하였을 때, 각각의 이름 공간(namespace)이 존재하기에 이름이 같더라도 구분할 수 있다.

 

또한 필드값만 공개되고 상수값은 클라이언트에 새겨지지 않기 때문에 새로운 상수를 추가하거나 순서를 바꾸게 되더라도 다시 컴파일하지 않아도 된다.

타입 안정성이 존재한다.

상수는 값으로 전달되기에 타입 안정성을 보장하기 힘들었지만, Enum은 각각의 타입이 정해져 있기에 타입 안정성을 보장할 수 있다.

 

메서드의 매개변수 타입으로 특정 타입을 지정해두면 해당 타입만 받을 수 있다.

 

checkHardLevel 메서드는 Hard 타입만 받을 수 있기에 Basic 타입이 들어올 경우 변경을 요구하고 있는 것을 확인할 수 있다.

활용하기

간단한 코드

public class EnumExample1 {
    private enum Season {
        SPRING, SUMMER, FALL, WINTER
    }

    public static void main(String[] args) {

        for(Season s : Season.values()) {
            System.out.println(s.name() + " / " + s.ordinal());
        }
    }
}

계절 정보를 담는 Season을 정의하고, 각각의 문자열과 순서를 출력하는 간단한 코드이다.

  • name() : 열거 객체의 문자열을 리턴한다.
  • ordinal() :열거 객체의 순서를 리턴한다.

발전된 코드

public class EnumExample2 {

    private enum Card {
        HEART(1),
        DIAMOND(2),
        SPADE(3),
        CLOVER(4);

        Card(int value) {
            this.value = value;
        }

        private final int value;
        public int value() { return value; }

    }

    public static void main(String[] args) {
        System.out.println(Card.HEART);
        System.out.println(Card.HEART.value());
    }
}
열거 객체에 데이터를 연결하고 메서드를 정의해서 사용하는 형태이다.

private final int value

  • 열거형 객체와 다른 값을 연결하기 위한 변수 선언이 필요하다.

Card(int value)

  • 생성자는 private만 허용하는데 열거 상수 옆에 붙는 형식으로 사용된다.

public int value()

  • 필요에 의해 메서드를 정의해서 사용할 수 있다.

마무리

장점

  • 이름 공간 및 타입 안정성 제공
  • 임의의 필드나 메서드 추가 가능
  • 인터페이스 구현 가능
  • 자동완성, 오타검증 등 IDE의 지원
  • 허용 가능한 값을 제한하고 리팩토링 시 범위가 최소화

단점

  • Integer, String에 비해 더 많은 메모리를 사용하기에 앱의 크기와 런타임 메모리 사용량의 증가

'Java' 카테고리의 다른 글

[Java] JDBC 개념 정리  (4) 2023.06.08
[Java] 상속을 언제 사용해야 할까  (8) 2023.03.26
[Java] 자바의 특징  (0) 2022.11.26
방어적 복사에서 clone은 안전한가  (0) 2022.07.12
Java 정규표현식  (0) 2022.06.23
댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Total
Today
Yesterday