본문 바로가기

Java

오늘의 질문 : Java의 Enum은 왜 생성자가 있는가?

자바의 Enum엔 특이하게도 생성자가 있다. 내가 주로 다루던 C++과는 다른 사용법이다. 일반적으로 Enum의 사용법은 상수를 열거하여 표현해야 할 때 주로 사용한다. 연관있는 상수들을 응집시키지 않고 열거하기만 하면 소스코드가 지저분해지고, 가독성이 떨어지기 때문이다.

자바에서는 왜 Enum에 생성자를 넣었을까.

이유를 알아보기 위해 C++의 Enum을 살펴보자.

C++에서는 Enum에 상수 값만 할당할 수 있다.

enum Type
{
	TYPE1 = 1, TYPE2, TYP3
}

그런데, 정수가 아닌 문자열을 할당하고 싶다면?

enum TYPE
{
	TYPE1 = 1, TYPE2, TYPE3
}

String TypeConverter(Type type)
{
	switch(type)
    {
    	case TYPE.TYPE1:
        return "Type1";
        ....
    }
}

위와 같이 별도의 변환 함수를 작성해야 한다. 어차피 문자열 상수를 표현하기 위한 함수인데, Enum과 함께 저장할 수 있으면 응집력이 더 올라갈 수 있지 않을까?

자바는 이런 질문을 해결하기 위해 문법적으로 class와 비슷하게 동작하도록 만들었다.

 

이제 자바의 Enum을 살펴보자.

public Enum Type{
	Type1("Type1", 1), Type2("Type2", 2), Type3("Type3", 3);
    private final String name;
    private final int value;
    pulbic Type(String name, int value){
    	this.name = name;
        this.value = value;
    }
}

관련 상수들을 Enum 클래스에 모아두고 생성자로 초기화함으로써 응집력이 더 좋아졌다.

 

그런데, 한 가지 물음이 든다. 문자열이나, 정수같은 상수는 비교할 수 있지만 생성자가 생김으로써 객체 간의 비교로 바뀌었다. 그렇다면 필연적으로 따라오는 것이 동등성, 동일성 문제이다.

자바는 인스턴스 간의 '==' 기호를 쓰면 레퍼런스 비교라고 알고 있는데, Enum은 어차피 상수인데 어떤 Enum 변수든 Type1 객체가 저장되면 비교 로직에서 true가 나와야 하는게 자연스럽다.

 

하지만 Enum안에 정의된 상수들은 final로 취급하기 때문에 == 기호를 쓰면 저장된 값들을 내부적으로 Hash 값으로 변환하여 비교한다. 따라서 true가 반환이 된다. (정말 놀랐다..)

 

결론 : Java의 Enum은 생성자를 추가함으로써 응집력을 더 좋게 만들었고, 내부 변수들은 final로 고정시켜 불변이 얻을 수 있는 이득도 얻었다.

'Java' 카테고리의 다른 글

Stream에 대하여  (0) 2022.02.10
Java의 static method는 왜 오버라이딩 되지 않는가  (0) 2022.01.23
자바 어노테이션  (0) 2021.07.08
모던 자바인액션 1장  (0) 2021.06.26
Java Collection  (0) 2021.04.01