IT

Enum으로 싱글 톤 구현하기 (Java)

lottoking 2020. 6. 1. 08:10
반응형

Enum으로 싱글 톤 구현하기 (Java)


나는 다음과 같은 것을 Singleton사용하여 Java 로 구현하는 것이 가능하다는 것을 읽었습니다 Enum.

public enum MySingleton {
     INSTANCE;   
}

그러나 위의 작동 방식은 무엇입니까? 구체적으로, Object인스턴스화해야합니다. 여기서 어떻게 MySingleton인스턴스화되고 있습니까? 누가하고 new MySingleton()있니?


이,

public enum MySingleton {
  INSTANCE;   
}

암시 적 빈 생성자가 있습니다. 대신 명시 적으로 작성하십시오.

public enum MySingleton {
    INSTANCE;
    private MySingleton() {
        System.out.println("Here");
    }
}

그런 다음과 같은 main()방법으로 다른 클래스를 추가하면

public static void main(String[] args) {
    System.out.println(MySingleton.INSTANCE);
}

당신은 볼 것이다

Here
INSTANCE

enum필드는 컴파일 시간 상수이지만 해당 enum유형의 인스턴스입니다 . 그리고 열거 형이 처음 참조 될 때 구성됩니다 .


enum유형의 특별한 유형입니다 class.

당신의 enum사실은 실제로 다음과 같이 컴파일됩니다

public final class MySingleton {
    public final static MySingleton INSTANCE = new MySingleton();
    private MySingleton(){} 
}

코드가 처음 액세스 하면 JVM INSTANCE이 클래스 MySingleton를로드하고 초기화합니다. 이 프로세스는 static필드를 한 (지연하게) 초기화합니다 .


Joshua Bloch 의이 Java 모범 사례 책 에서 개인 생성자 또는 Enum 유형으로 Singleton 속성을 적용해야하는 이유를 설명 할 수 있습니다. 이 장은 매우 길기 때문에 요약하여 보관하십시오.

클래스를 Singleton으로 만들면 클라이언트 유형을 테스트하는 인터페이스를 구현하지 않는 한 싱글 톤을 모의 구현으로 대체 할 수 없으므로 클라이언트 테스트가 어려워 질 수 있습니다. 권장되는 접근 방식은 하나의 요소로 열거 형을 간단히 만들어 싱글 톤을 구현하는 것입니다.

// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}

이 방법은보다 간결하고 직렬화 기계를 무료로 제공하며 정교한 직렬화 또는 리플렉션 공격에도 불구하고 다중 인스턴스화에 대한 확실한 보장을 제공한다는 점을 제외하고는 공공 현장 접근 방식과 기능적으로 동일합니다.

이 방법은 아직 널리 채택되지 않았지만 단일 요소 열거 형 유형이 단일 톤을 구현하는 가장 좋은 방법입니다.


모든 열거 형 인스턴스와 마찬가지로 Java는 클래스가로드 될 때 각 객체를 인스턴스화하며 JVM 마다 정확히 한 번 인스턴스화되도록 보장합니다 . INSTANCE선언을 공개 정적 최종 필드로 생각하십시오 . Java는 클래스가 처음 참조 될 때 오브젝트를 인스턴스화합니다.

인스턴스는 정적 초기화 중에 작성되는데, 이는 Java 언어 스펙, 섹션 12.4에 정의되어 있습니다.

가치가있는 것에 대해 Joshua Bloch 는이 패턴을 Effective Java Second Edition 의 항목 3으로 자세히 설명합니다 .


Singleton Pattern 은 개인 생성자를 가지고 인스턴스화를 제어하기 위해 몇 가지 메소드를 호출하는 것에 관한 것이므로 (일부처럼 getInstance) Enums에는 이미 암시 적 개인 생성자가 있습니다.

JVM 또는 일부 컨테이너 가 어떻게 우리 인스턴스를 제어 하는지 알지 Enums못하지만 이미 암시 적 Singleton Pattern인 것을 사용하는 것처럼 보입니다 . 차이점은 우리가 전화하지 않고 getInstanceEnum이라고 부르는 것입니다.


As has, to some extent, been mentioned before, an enum is a java class with the special condition that its definition must start with at least one "enum constant".

Part from that, it's a class like any class and you use it by adding methods below the constant definitions:

public enum MySingleton {
    INSTANCE;

    public void doSomething() { ... }

    public synchronized String getSomething() { return something; }

    private String something;
}

You access the singleton's methods along these lines:

MySingleton.INSTANCE.doSomething();
String something = MySingleton.INSTANCE.getSomething();

The use of an enum, instead of a class, is, as has been mentioned in other answers, mostly about a thread-safe instantiation of the singleton and a guarantee that it will always only be one copy.

And, perhaps, most importantly, that this behavior is guaranteed by the JVM itself and the Java specification.

Here's a section from the Java specification on how multiple instances of an enum instance is prevented:

An enum type has no instances other than those defined by its enum constants. It is a compile-time error to attempt to explicitly instantiate an enum type. The final clone method in Enum ensures that enum constants can never be cloned, and the special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization. Reflective instantiation of enum types is prohibited. Together, these four things ensure that no instances of an enum type exist beyond those defined by the enum constants.

Worth noting is that after the instantiation any thread safety concerns must be handled like in any other class with the synchronized keyword etc.

참고URL : https://stackoverflow.com/questions/26285520/implementing-singleton-with-an-enum-in-java

반응형