자바의 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 |