Enum
은 몇 가지의 한정된 값만을 가진다.
만약 Week
라는 Enum
을 정의한다면 월,화,수,목,금,토,일 7개의 값만 가지게 될 것이다.
Enum
은 몇가지 특징을 가지고 있다.
Enum
은 암묵적으로 java.lang.Enum
을 상속받는다.generic
을 지원하지 않는다.abstract
메소드를 가질 경우에public enum Week { MONDAY { @Override void sayHello() { System.out.println("Hello, Monday"); } }, ... ... FRIDAY { @Override void sayHello() { System.out.println("Hello, Friday"); } }; abstract void sayHello(); }
new
를 통해 인스턴스화할 수 없다.기본 생성자가 있긴한데
private
으로 선언이 되어 있다.
또, 열거 상수에 매개변수를 추가할 때 마다 필드가 늘어나는데 필드가 늘어나면 반드시 생성자가 필요하다. 그러나 생성자로는 인스턴스를 생성하지 않고 반드시Week.MONDAY
와 같이 생성한다.
생성자는 각각의 열거상수를 힙 스택에 생성할 때JVM
이 사용하는 것 같다.
열거타입과 열거상수로 이루어져있다.
Enum
자체로도 .java
파일을 이룰 수 있고 다른 클래스 안에 정의될 수도 있다.
만약 멤버 변수, 멤버 메소드를 포함한다면 열거 상수는
;
으로 끝나야하며 반드시 멤버 변수, 멤버 메소드보다 앞에 등장해야 한다.
또한 열거 상수는 매개변수를 가질 수 있다. 매개변수를 가지는 만큼 필드가 추가되어야 하고 필드를 매개변수로 받는 생성자를 반드시 정의해야 한다.
생성자를 선언하지만 new
를 사용해서 생성자를 호출하여 Enum 인스턴스를 생성할 수 없다.
프로그램이 실행될 때 Enum
은 각각의 상수들의 숫자만큼 객체로 만들어져 힙 영역에 자동으로 생성된다. 즉 Week
의 경우 월~일까지 7개의 Week
인스턴스가 생성되는 것이다.
이미 생성되어 있기 때문에 Week w = Week.MONDAY
와 같이 상수를 할당하듯 할당하면 되며 같은 값이라면 열거상수라면 같은 메모리 주소를 참조한다.
Week w1 = Week.FRIDAY;
Week w2 = Week.FRIDAY;
Week w3 = Week.MONDAY;
System.out.println(w1.hashCode());
System.out.println(w2.hashCode());
System.out.println(w3.hashCode());
실제로 w1
과 w2
의 hashCode
가 같다.
Week.values()
를 입력하면 모든 열거상수를 리턴한다.
리턴 값은 열거타입이다.
for (Week w : Week.values()) {
System.out.println(w);
}
두 가지 형태가 있다.
Week.valueOf(String)
우리가 정의한 열거타입이 매개변수로 넘겨준 문자열과 동일한 열거상수를 리턴한다.
for (Week w : Week.values()) {
System.out.println(Week.valueOf(w.toString()));
}
Enum.valueOf(Class<T>, String)
Enum
의 static method
이다.
우리가 정의한 열거 타입을 첫번째 매개변수로 넘겨주고 두번째 문자열을 넘겨주면 첫번째 매개변수가 가진 두번째 매개변수를 리턴해준다.
for (Week w : Week.values()) {
System.out.println(Week.valueOf(Week.class, w.toString()));
}
두 메소드 모두 null
을 넘겨주던가 일치하는 열거상수가 없다면 Exception
이 발생한다.
우리가 정의한 enum 클래스는 java.lang.Enum
을 자동으로 상속받는다. 따라서 우리가 정의한 enum 클래스는 다른 클래스를 상속받을 수 없다.
Enum
은 Object
를 직접적으로 상속받는다. 위에서 언급한 것처럼 Enum
의 생성자는 사용자가 호출할 수없고 컴파일러가 호출할 수 있다.
Set
을 Enum
과 사용하기 좋도록 특수한 형태로 구현한 클래스이다.
마찬가지로 EnumSet
또한 생성자를 통해 생성하지 않는다. static method
를 통해 생성할 수 있다.
EnumSet.allOf(Class<T>)
: 매개변수로 받은 enum 클래스의 모든 열거 상수를 가진 EnumSet<T>
리턴EnumSet.of(Enum...)
: 매개변수로 받은 열거 상수을 가진 EnumSet
리턴EnumSet<Week> es = EnumSet.allOf(Week.class);
EnumSet es2 = EnumSet.of(Week.MONDAY); // 제네릭이 없어도 됨
System.out.println(es);
System.out.println(es2);