enum 으로 생성한 클래스 객체가 싱글톤인 이유?

프로그래밍|2013. 3. 5. 17:14

enum을 이용하여 클래스를 정의하면 어떤 원리에 의해서 싱글톤으로 제공하는지, 그리고 멤버 변수가 있는데도 thread-safe한지 그 이유에 대해서 알아봤다.


public enum EnumClassTest {


INSTANCE1("instance1")

, INSTANCE2("instance2");


static {

System.out.println("init!!");

}


private String objName;


private EnumClassTest(String objName) {

this.objName = objName;

}


public String getObjName() {

return objName;

}


public static void main(String[] args) {

EnumClassTest[] type = EnumClassTest.values();

for (EnumClassTest enumType : type) {

System.out.println("hashCode=" + enumType.hashCode());

System.out.println("name=" + enumType.name());

System.out.println("valueOf=" + EnumClassTest.valueOf(enumType.name()));

System.out.println("ordinal=" + enumType.ordinal());

System.out.println("declaringClass=" + enumType.getDeclaringClass());

System.out.println("objName=" + enumType.getObjName());

System.out.println("=====================================================");

}

}

}


javap 명령어를 통해 클래스 파일을 원시 코드로 역어셈블하면 아래와 같은 코드가 나온다.

D:\dev\workspace\project\CardBill\target\classes\com\kyu\excel\enumtype>javap EnumClassTest

Compiled from "EnumClassTest.java"

public final class com.kyu.excel.enumtype.EnumClassTest extends java.lang.Enum<com.kyu.excel.enumtype.EnumClassTest> {

  public static final com.kyu.excel.enumtype.EnumClassTest INSTANCE1;

  public static final com.kyu.excel.enumtype.EnumClassTest INSTANCE2;

  static {};

  public java.lang.String getObjName();

  public static void main(java.lang.String[]);

  public static com.kyu.excel.enumtype.EnumClassTest[] values();

  public static com.kyu.excel.enumtype.EnumClassTest valueOf(java.lang.String);

}


중요하게 봐야 할 부분이 INSTANCE1, INSTANCE2 이다.

static final이면서 EnumClassTest type으로 선언되어 있다. 아마도 JVM에서는 EnumClassTest 초기화 시 각 상수에 있는 갯수만큼 EnumClassTest 타입의 객체를 생성하여 각 상수에 주입해 줄 것이라 예상된다.

그래서 각 상수는 싱글톤으로 생성되고, objName 멤버 변수는 thread-safe하게 유지될 수 있는 것이다.


간단하게 말해서 다음과 같이 객체를 두 번 생성한 것과 같다.

EnumClassTest INSTANCE1 = new EnumClassTest();

EnumClassTest INSTANCE2 = new EnumClassTest();


각 상수의 객체 레퍼런스가 다르 다는 것은 hashcode를 찍어보면 알 수 있다.

## INSTANCE1

hashCode=12677476

name=INSTANCE1

valueOf=INSTANCE1

ordinal=0

declaringClass=class com.kyu.excel.enumtype.EnumClassTest

objName=instance1


## INSTANCE2

hashCode=33263331

name=INSTANCE2

valueOf=INSTANCE2

ordinal=1

declaringClass=class com.kyu.excel.enumtype.EnumClassTest

objName=instance2

댓글()