
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);
