2017년 7월 7일 금요일

[Java] enum(Enumeration) 클래스

비교를 위한 상수가 필요하다면 어떻게 할까, 예를들어 옷집의 옷사이즈 small, medium, large 사이즈가 있다고 하자. small = 1, medium = 2, large = 3 이런식으로 정수형 상수로 대체하는것도 한가지 방편이다. 하지만 이런 방식은 상수(Constant)가 많아지면 많아질수록 사용자의 실수로 인해 에러를 만들 가능성이 존재한다. 또 코드를 수정하게 되면 엄청 골치아플것이다. 그래서 Java SE 1.5버젼부터 더 좋은 enum 클래스가 만들어졌다.
만약 무언가를 비교하기 위한 상수가 필요하다면 enum 클래스를 이용해 상수를 생성할 수 있다.


public enum Size {
    SMALL, MEDIUM, LARGE;
}
간단하게 Small 사이즈, Medium 사이즈, Large 사이즈를 위한 상수를 생성했다. 그냥 3줄짜리 클래스인데 가능하다. 이 enum 클래스에서 생성되는 인스턴스는 위 코드에
열거된 3개뿐이고, 이런 enum 클래스를 이용해서 새로운 객체를 생성하는것은 불가능하다. 그래서 enum 클래스의 인스턴스를 비교할려면 equals 같은 메소드를 쓰지 않고 그냥 연산자 "=="로 쉽게 비교가 가능하다.


Size x = Size.SMALL;
Sise y = Size.SMALL;
Size z = Size.LARGE;
x==y // true
x==z // false

또 원한다면 생성자 함수와 원하는 데이터 필드를 추가해 enum 클래스를 약간 손볼수도 있다. 다만 생성자 함수는 열거된 상수(Constant)들이 생성될때만 한번 호출된다. 그렇기 때문에 컴파일 시점이 지난 후에는 호출할 수 없다. 물론 accessor 메소드들은 언제든 접근이 가능하다.


public enum Size {
    SMALL("S"), MEDIUM("M"), LARGE("L");
    
    private String keyword;
    private Size(String k){
    this.keyword = k;
    }
    public String getKeyword(){
    return this.keyword;
    }
}

모든 열거된 형(Small, Medium, Large)들이 Enum 클래스를 상속한다. 그렇기 때문에 Enum 클래스에서 정의된 메소드들을 사용할 수 있다. 가장 자주 사용되는것은 toString 메소드로, 해당 타입의 이름을 반환한다. Size.SMALL.toString은 String 타입 "SMALL"을 반환하게 된다. 물론 오버라이딩해서 새로 정의할수도 있다. 이걸 반대로 이용하는 메소드는 valueOf 메소드 이다. 파라미터로 원하는 enum 클래스와 해당 타입의 이름값을 주면 그 상수를 반환한다.


Size.SMALL.toString(); // SMALL
Size.LARGE.toString(); // LARGE
Size.MEDIUM.toString(); // MEDIUM
Size x = Enum.valueOf(Size.class, "SMALL"); //Size.SMALL
Size y = Size.SMALL;
x == y // true

모든 enum 인스턴스는 static 속성을 가진 values 메소드를 가지고 있다. 이 메소드는 해당 클래스에 열거된 상수들의 배열을 반환한다. 또한 ordinal 메소드는 상수들의 배열에서 각 상수의 인덱스를 반환한다.


Size[] values = Size.values(); // {Size.SMALL, Size.MEDIUM, Size.LARGE}를 반환한다.
Size.MEDIUM.ordinal(); //1을 반환함
Size.SMALL.ordinal(); //0을 반환함
Size.LARGE.ordinal(); //2을 반환함

댓글 없음:

댓글 쓰기