지연 초기화(Lazy Initialization)이란? 필드의 초기화 시점을 그 값이 처음 필요할 때까지 늦추는 기법이다. 이로 인해 값이 전혀 사용되지 않으면 초기화도 결코 일어나지 않기에 자원을 아낄 수 있다.
자바에서 지연 초기화에 대한 글을 찾기가 어렵다. 유튜브에는 나오지도 않을 뿐더러, 내가 본 책에도 없는 내용이었다. 다만 '이펙티브 자바'라는 유명한 책에서 해당 부분에 대한 설명이 조금 나오는 것 같다.
아래 글은 추상적이고 부정확할 수 있다는 점을 고려해주면 좋겠다.
public class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
위 코드에서 singleInstanceHolder라는 내부 클래스는 static으로 선언 돼 있더라도 클래스 로딩 시점에 인스턴스는 생성되지 않는다.
자바에서 클래스 로딩은 지연 초기화 방식을 따른다. 즉, 클래스가 처음으로 사용되는 시점에 로딩되고 초기화된다. 이로 인해 메모리를 효율적으로 사용할 수 있다.
위와 같이 싱글톤 패턴을 구현한다면, singleInstanceHolder라는 내부 클래스는 Singleton 클래스의 getInstance()메서드를 호출할 때만 로딩된다. 그리고 이 때 singleInstanceHolder 내부 클래스의 정적 필드인 INSTANCE가 생성된다.
이렇게 하면 싱글톤 인스턴스는 필요한 시점에 생성되며, 프로그램 실행 중 getInsatnce()를 한번도 실행하지 않는다면, singleInstanceHolder는 생성되지 않고 자원을 아낄 수 있다.
위의 싱글톤 예제처럼 클래스는 지연 초기화 방식을 따른다는 특징을 이용해 만들어진것이 바로 '지연 초기화 홀더 클래스' 방식이다. 위처럼 내부 Holder클래스를 활용하여 초기화를 지연시켜두는 방식이다.
만들어진 Holder클래스를 어디선가 사용하면 그 때 초기화가 수행되고 이를 지연 초기화 했다고 말할 수 있다.