enum은 사실 클래스다. 그렇기 때문에 생성자를 가질 수 있다. 아래와 같이 코드를 수정해보자.
package org.opentutorials.javatutorials.constant2; enum Fruit{ APPLE, PEACH, BANANA; Fruit(){ System.out.println("Call Constructor "+this); } } enum Company{ GOOGLE, APPLE, ORACLE; } public class ConstantDemo { public static void main(String[] args) { /* if(Fruit.APPLE == Company.APPLE){ System.out.println("과일 애플과 회사 애플이 같다."); } */ Fruit type = Fruit.APPLE; switch(type){ case APPLE: System.out.println(57+" kcal"); break; case PEACH: System.out.println(34+" kcal"); break; case BANANA: System.out.println(93+" kcal"); break; } } }
차이점
결과는 아래와 같다.
Call Constructor APPLE Call Constructor PEACH Call Constructor BANANA 57 kcal
Call Constructor가 출력된 것은 생성자 Fruit가 호출되었음을 의미한다. 이것이 3번 호출되었다는 것은 필드의 숫자만큼 호출되었다는 뜻이다. 즉 enum은 생성자를 가질 수 있다.
하지만 코드를 아래와 같이 바꾸면 컴파일 에러가 발생한다.
enum Fruit{ APPLE, PEACH, BANANA; public Fruit(){ System.out.println("Call Constructor "+this); } }
이것은 enum의 생성자가 접근 제어자 private만을 허용하기 때문이다. 덕분에 Fruit를 직접 생성할 수 없다. 그렇다면 이 생성자의 매개변수를 통해서 필드(APPLE..)의 인스턴스 변수 값을 부여 할 수 있다는 말일까? 있다. 그런데 방식이 좀 생경하다.
package org.opentutorials.javatutorials.constant2; enum Fruit{ APPLE("red"), PEACH("pink"), BANANA("yellow"); public String color; Fruit(String color){ System.out.println("Call Constructor "+this); this.color = color; } } enum Company{ GOOGLE, APPLE, ORACLE; } public class ConstantDemo { public static void main(String[] args) { /* if(Fruit.APPLE == Company.APPLE){ System.out.println("과일 애플과 회사 애플이 같다."); } */ Fruit type = Fruit.APPLE; switch(type){ case APPLE: System.out.println(57+" kcal, "+Fruit.APPLE.color); break; case PEACH: System.out.println(34+" kcal"+Fruit.PEACH.color); break; case BANANA: System.out.println(93+" kcal"+Fruit.BANANA.color); break; } } }
차이점
실행결과는 아래와 같다.
Call Constructor APPLE Call Constructor PEACH Call Constructor BANANA 57 kcal, red
아래 코드는 Fruit의 상수를 선언하면서 동시에 생성자를 호출하고 있다.
APPLE("red"), PEACH("pink"), BANANA("yellow");
아래 코드는 생성자다. 생성자의 매개변수로 전달된 값은 this.color를 통해서 5행의 인스턴스 변수의 값으로 할당된다.
Fruit(String color){ System.out.println("Call Constructor "+this); this.color = color; }
아래처럼 호출하면 APPLE에 할당된 Fruit 인스턴스의 color 필드를 반환하게 된다.
System.out.println(57+" kcal, "+Fruit.APPLE.color);
열거형은 메소드를 가질수도 있다. 아래 코드는 이전 예제와 동일한 결과를 출력한다.
package org.opentutorials.javatutorials.constant2; enum Fruit{ APPLE("red"), PEACH("pink"), BANANA("yellow"); private String color; Fruit(String color){ System.out.println("Call Constructor "+this); this.color = color; } String getColor(){ return this.color; } } enum Company{ GOOGLE, APPLE, ORACLE; } public class ConstantDemo { public static void main(String[] args) { Fruit type = Fruit.APPLE; switch(type){ case APPLE: System.out.println(57+" kcal, "+Fruit.APPLE.getColor()); break; case PEACH: System.out.println(34+" kcal"+Fruit.PEACH.getColor()); break; case BANANA: System.out.println(93+" kcal"+Fruit.BANANA.getColor()); break; } } }
차이점
enum은 맴버 전체를 열거 할 수 있는 기능도 제공한다.
package org.opentutorials.javatutorials.constant2; enum Fruit{ APPLE("red"), PEACH("pink"), BANANA("yellow"); private String color; Fruit(String color){ System.out.println("Call Constructor "+this); this.color = color; } String getColor(){ return this.color; } } enum Company{ GOOGLE, APPLE, ORACLE; } public class ConstantDemo { public static void main(String[] args) { for(Fruit f : Fruit.values()){ System.out.println(f+", "+f.getColor()); } } }
열거형의 특성을 정리해보자. 열거형은 연관된 값들을 저장한다. 또 그 값들이 변경되지 않도록 보장한다. 뿐만 아니라 열거형 자체가 클래스이기 때문에 열거형 내부에 생성자, 필드, 메소드를 가질 수 있어서 단순히 상수가 아니라 더 많은 역할을 할 수 있다.