2016-09-14 2 views
1

나는이 자습서를 수행하고있어 당신의 싱글 톤 클래스는 많은 자원을 사용하지 않는 경우 http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examplesgetInstance() 또는 getInstance() 전에 인스턴스화가 발생 했습니까? 싱글을 생성하기위한

public class EagerInitializedSingleton { 

    private static final EagerInitializedSingleton instance = new EagerInitializedSingleton(); 

    //private constructor to avoid client applications to use constructor 
    private EagerInitializedSingleton(){} 

    public static EagerInitializedSingleton getInstance(){ 
     return instance; 
    } 
} 

아래의 방법이 사용하기에 접근 방식 인 경우 소유자는 의견이있다. 그러나 대부분의 시나리오에서 파일 시스템, 데이터베이스 연결 등 및 과 같은 리소스에 대해 Singleton 클래스는 입니다. 클라이언트가 getInstance 메서드을 호출하지 않는 한 인스턴스화는 피해야합니다.

문제는 :

그들은 항상했을 때 내가 (객체 인스턴스의)이 코드에서 인스턴스화를 알고 클라이언트 방법 의 getInstance를 호출하지 않는 한 때까지하지만 우리가 인스턴스화하지 않도록해야 말 클래스 EagerInitializedSingleton로드 및 EagerInitializedSingleton은 호출 할 때만로드됩니다. EagerInitializedSingleton.getInstance()
=> 인스턴스화는 getInstance() 및 그 이전에는 발생하지 않았으며 시간이 지나면 발생했습니다. getInstance()

,

기준 (클래스 로더 처음 클래스를로드 할 때)

정적 변수가 실행을 시작할 때, 단 한번 초기화된다. (https://stackoverflow.com/a/8704607/5381331)

클래스가로드되는시기는 언제입니까? -;
- 상기 바이트 코드는, 예를 들면 클래스 (시스템에 정적 참조 할 때, 새로운 바이트 코드를 실행한다 (예를 들어, FooClass F = 새로운 FooClass())
:
는 정확히 두 개의 경우가있다. out) (http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html)

내가 틀렸거나 정확하지 않습니까? 제발 좀 줘.

답변

2

해당 코드가있는이 경우 일 것입니다. 아마도입니다. 당신이 EagerInitializedSingletonstatic 방법, 또는 이전에 getInstance의 호출에 코드베이스 어딘가에 참조 EagerInitializedSingletonstaticfinal 회원이 있다면

그러나, EagerInitializedSingletoninstance 변수는 초기화됩니다.

EagerInitializedSingleton 클래스의 반사 호출이 Class.forName 인 것과 같습니다.

게으른 초기화 또는 열거 형을 포함하여 싱글 톤을 선언하는 다른 방법이 있다는 점에 유의하십시오.

+0

잘 설명해 주셔서 감사합니다. 그것은 내가 Java를 이해하는 데 도움이됩니다 –

+0

@ PhanVanLinh 당신을 환영합니다! – Mena

1

나는 문제가 인스턴스를 가져올 필요없이로드되지만 다른 이유로 인해 발생한다고 생각합니다.사용자가 그 싱글 톤의 인스턴스를 얻고 자 할 때 클래스가 처음 사용될 것이라고 가정하지만, 다른 이유로 인해 발생할 수도 있습니다. 클래스 로더를 호출하거나 일부 타사 소프트웨어를 사용하여 클래스를로드하고 있지만 싱글 톤의 인스턴스를 얻지는 않는다는 것을 염두에 두어야합니다.

+0

클래스 초기화와 클래스 로딩이 완전히 섞여 있습니다. –

1

그들은 클라이언트가 는 getInstance 메소드

솔루션은 게으른로드를 호출하지 않는 한 때까지 우리가 인스턴스화하지 않도록해야한다고. 클래스 뭔가가 JVM에 의해로드 된 경우

wikipedia, Initialization-on-demand holder idiom에서, 클래스는 초기화를 통해 이동합니다. 클래스에는 에 대한 정적 변수가 없기 때문에 초기화가 거의 완료됩니다. 정적 클래스 정의 LazyHolder는 LazyHolder가 실행되어야한다고 JVM 이 결정할 때까지 초기화되지 않습니다. 정적 클래스 LazyHolder는 정적 메서드 getInstance가 Something 클래스에서 호출 된 일 때만 실행되며 처음 발생하면 JVM이 LazyHolder 클래스를로드하고 초기화합니다.

public class Something { 
    private Something() {} 

    private static class LazyHolder { 
    private static final Something INSTANCE = new Something(); 
    } 

    public static Something getInstance() { 
    return LazyHolder.INSTANCE; 
    } 
} 
관련 문제