1. Enum이란?
- 상수들의 집합
- 자바에서는 final로 원시 타입 값을 고정할 수 있음
- 상수만으로 작성된 클래스는 class로 선언하지 않고 enum으로 선언할 수 있다.
2. Enum이 없다면?
- 우선 enum이 필요한 이유에 대해 생각해 보면, 특정 상수에 명시적인 의미를 부여하기 위함이 크다고 생각한다.
- 위에서 언급했듯, java에서는 final로 원시 타입 값을 고정할 수 있기 때문에 이를 활용하면 된다.
public class tmp {
private final static int MONDAY = 1;
private final static int TUESDAY = 2;
private final static int WEDNESDAY = 3;
private final static int THURSDAY = 4;
private final static int FRIDAY = 5;
private final static int SATURDAY = 6;
private final static int SUNDAY = 7;
/*
생략
*/
}
- 위 방식은 final을 사용하여 한번 지정하면 바뀌지 않게 설정하면서 동시에 static을 사용하여 메모리에 한 번만 할당되도록 설정되었다.
- 또한, 변수명을 통해 그 의미를 명확하게 알 수 있다.
- 이렇게 써도 웬만한 경우는 커버가 될 것 같다.
- 또 하나의 방법으로, 아래와 같은 방법이 있다.
class Day{
public final static Day MONDAY = new Day();
public final static Day TUESDAY = new Day();
public final static Day WEDNESDAY = new Day();
/*
생략
*/
}
- 위 방식 또한 final과 static 키워드를 사용하였고 변수명을 통해 값에 대한 의미를 명시하였다.
- 각 변수에 할당되는 객체는 모두 각각 생성하고 있으므로 다른 객체로 구분될 수 있다.
3. java의 enum 사용하기
- 위 방식으로 많은 부분이 커버되지만 java 1.5부터는 해당 패턴을 문법적으로 지원하여 더욱 편리하고 명시적으로 사용할 수 있도록 하였다.
- 바로 위의 코드는 enum 타입을 써서 아래와 같이 바꿀 수 있다.
//class Day{
// public final static Day MONDAY = new Day();
// public final static Day TUESDAY = new Day();
// public final static Day WEDNESDAY = new Day();
// /*
// 생략
// */
//}
enum Day{
MONDAY,TUESDAY,WEDNESDAY
}
- 해당 코드가 갖는 의미를 알기 위해 디버깅해 보면
- enum으로 선언된 각각의 필드는 [name, ordinal] 속성을 가지는 것을 확인할 수 있다.
- name 속성은 선언된 문자열 값 자체이다.
- ordinal은 선언된 순서에 따라 부여된 번호이다.
- java의 enum은 name과 ordinal과 관련한 여러 편의 메소드를 제공
- enum은 인스턴스 생성이 안 됨(상수 본연의 의미를 갖기 위함)
4. java enum의 확장
- java enum은 class 개념도 포함한다. -> 추가적인 생성자, 메소드, 필드를 가질 수 있다.
- 주의할 점은, 생성자의 경우 무조건 private 만 가능하다. -> 외부에서 인스턴스 생성 불가능 -> 싱글톤을 강제함
- 그런데, enum을 공부하는 중 조금 이상한 부분을 발견했다.
enum RoadSide{
Left("왼쪽"),
Right("오른쪽");
private String krName;
private RoadSide(){
}
private RoadSide(String krName){
this.krName = krName;
}
public String getKrName(){
return this.krName;
}
// 하면 안되는 부분
// enum은 컴파일 타임에 고정되는 상수의 의미를 갖는데, 이 코드로 인해 런타임에 바뀔 수 있는 가능성이 생긴다!
// java 문법에서 public 생성자는 막지만 이 부분은 안막았으니 주의할것
public void setKrName(String krName){
this.krName = krName;
}
}
public class tmp {
public static void main(String[] args){
System.out.println(RoadSide.Left.getKrName());
RoadSide.Left.setKrName("왼쪽foo");
System.out.println(RoadSide.Left.getKrName());
/*
생략
*/
}
}
- 해당 코드를 실행해 보니 아래와 같은 결과가 나온다.
- 즉, enum의 경우 public 생성자를 막아 싱글톤 패턴을 강제하지만, 별도의 필드를 가질 경우 setter에 대한 제약은 없다는 것을 발견했다.
- 누가 굳이 이런 코드를 작성할까 하지만, enum의 필드를 둘 때 setter를 생성하지 않도록 해야 한다.(개발자의 실수를 java 문법에서 잡아주지는 않기 때문)
5. 정리
- enum의 장점
- 상수에 대한 명시적인 의미를 부여할 수 있다.
- 코드가 단순해지며 가독성이 좋아진다.
- 인스턴스 생성과 상속을 방지한다.
- 구현의 의도를 명시적으로 표현할 수 있다.
- 개별 필드와 메소드를 가질 수 있으므로 확장 가능성이 있다.
- 주의할 점
- enum을 확장하기 위한 메소드를 만들 때 이미 생성된 enum 값을 바꾸는 메소드를 만들지 않도록 유념하기
6. 참고
7. 확장
- Enum을 jpa환경에서 사용하기: https://jojoldu.tistory.com/122
- Enum을 mybatis환경에서 사용하기: https://minkwon4.tistory.com/169
'java > 기타' 카테고리의 다른 글
[Collection Framework] 정리 (0) | 2022.01.04 |
---|---|
Thread pool vs Reactive (0) | 2021.12.01 |
JDBC Connection pool 모니터링 지표에 대한 이해 (0) | 2021.12.01 |
java - Exception과 logging이 성능에 미치는 영향 (0) | 2021.10.08 |
java - InputStream& OutputStream close (0) | 2021.09.28 |
댓글