static 블록 vs 싱글톤 (Singleton) - ddingmin/be-was GitHub Wiki

static 블록

static 블록은 클래스가 로드될 때 단 한번만 실행되는 블록이다. static 블록에 존재하는 코드들은 이 시점에서 실행된다.

보통 클래스들을 초기화하기 위한 목적으로 사용된다. 이 방법을 통해서 클래스 변수를 초기화 하거나 초기 설정을 수행할 수 있다.

static은 전역 변수와 같이 사용될 수 있으므로, 모든 인스턴스가 공통적으로 사용해야 하는 데이터를 초기화 하는 용도로 사용된다.

또한 static 블록은 클래스의 인스터스 생성과는 별개로 실행된다.

public class MyClass {
    private static int count;

    static {
        // 클래스가 로딩될 때 한 번만 실행되는 static 블록
        count = 0;
    }
}

다음과 같은 코드로 예를 들 수 있다. 지금은 단순히 count 변수를 0으로 초기화 하는 단순한 코드이지만, 필요에 따라 특정 로직을 통해 초기화 해줄 수 있다.

싱글톤 패턴

싱글톤 패턴은 오직 한 가지 인스턴스만 생성할 수 있도록 하는 디자인 패턴이다.

싱글톤도 마찬가지로 전역 변수처럼 자원을 공유해야 하는 경우에 사용된다.

보통 생성자의 접근 제어자를 private 로 지정해 외부의 접근을 제어하고, 정적 메서드를 통해 항상 같은 인스턴스를 반환하도록 구현한다.

public class MySingleton {
    private static MySingleton instance;

    private MySingleton() {
        // private 생성자로 외부에서 직접 인스턴스 생성 불가능
    }

    public static MySingleton getInstance() {
        if (instance == null) {
            instance = new MySingleton();
        }
        return instance;
    }
}

다음 코드는 지연 생성을 적용한 코드이다. 싱글톤 패턴의 생성 방식은 지연 생성과 동시성 문제가 발생할 수 있어 이를 해결하기 위한 다양한 방법이 있다.

싱글톤 패턴은 변수를 초기화 하는 것이 아닌 단 하나의 인스턴스를 사용함을 보장하기 위한 방식이다.

차이점?

사실 static 블록과 싱글톤 패턴은 목적부터 다르다.

static 블록은 단순히 초기화를 위한 수단이라고 생각하면 될 것 같다. 모든 인스턴스가 사용하기위한 값을 초기화 하기 위해 사용한다.

하지만 싱글톤 패턴은 단 하나의 인스턴스를 생성해 사용하기 위해 사용된다.

→ 즉, 쉽게 생각해 전역 변수를 초기화하기 위해 사용되는 싱글톤 패턴과 단 하나의 전역 객체를 사용하기 위한 방법으로 이해하면 쉬울 것 같다.

성능

static 블록은 클래스가 로드되는 시점에서 한 번 실행된다. 이후 이를 가져다 사용할 때는 아무런 제약이 없다.

싱글톤 패턴은 인스턴스를 생성한 뒤 사용하기에, 오버헤드가 존재할 수 있다. 또한 멀티 스레드 환경에서 동시성 문제가 발생한다. 이를 해결하기 위해 사용되는 오버헤드도 존재할 수 밖에 없다.