본문 바로가기
이펙티브 자바

아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라

by 아토로 2022. 5. 16.

싱글턴(ingleton)이란 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다.

private 생성자 + public static final 필드

public class Elvis {

    public static final Elvis INSTANCE = new Elvis();

    private Elvis() {
    }
}

장점

  • 간결하고 싱글턴임을 API에 드러낼 수 있다.

단점

  • 싱글턴을 사용하는 클라이언트가 테스트하기 어려워진다.
  • 리플렉션으로 private 생성자를 호출할 수 있다.
  • 역직렬화 할 때 새로운 인스턴스가 생길 수 있다.

private 생성자 + 정적 팩터리 메서드

public class Elvis {

    private static final Elvis INSTANCE = new Elvis();

    private Elvis() {
    }

    public static Elvis getInstance() {
        return INSTANCE;
    }
}

장점

  • API를 바꾸지 않고도 싱글턴이 아니게 변경할 수 있다.
  • 정적 팩터리를 제네릭 싱글턴 팩터리로 만들 수 있다.
  • 정적 팩터리의 메서드 참조를 공급자(supplier)로 사용할 수 있다.

열거 타입(Enum)

public enum Elvis {
    INSTANCE
}
  • 가장 간결한 방법이며 직렬화와 리플렉션에도 안전하다.
  • 대부분의 상황에서는 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.

완벽 공략

메서드 참조

  • 메서드 하나만 호출하는 람다 표현식을 줄여서 쓰는 방법

함수형 인터페이스

  • 함수형 인터페이스는 람다 표현식과 메서드 참조에 대한 “타겟 타입"을 제공한다.
  • 타겟 타입은 변수 할당, 메서드 호출, 타입 변환에 활용할 수 있다.

객체 직렬화

  • 바이트 스트림으로 변환한 객체를 파일로 저장하거나 네트워크를 통해 다른 시스템으로 전송할 수 있다.
  • Serializable 인터페이스 구현
  • transient: 직렬화 하지 않을 필드 선언
  • serialVersionUID가 일치해야만 역직렬화가 가능하며, 명시적으로 선언하지 않으면 자동 생성된다.
  • 역직렬화 방지 방법
private Object readResolve() {
    return INSTANCE;
}

테스트 코드

https://github.com/jsyang-dev/study-effective-java/tree/master/src/item03

 

GitHub - jsyang-dev/study-effective-java

Contribute to jsyang-dev/study-effective-java development by creating an account on GitHub.

github.com

관련 글

2021.12.29 - [GoF의 디자인 패턴] - 싱글톤(Singleton) 패턴

 

싱글톤(Singleton) 패턴

인스턴스를 오직 한 개만 제공하는 클래스 시스템 런타임, 환경 세팅에 대한 정보 등, 인스턴스가 여러 개 일 때 문제가 생길 수 있는 경우가 있다. 인스턴스를 오직 한 개만 만들어 제공하는 클

jsyang-dev.tistory.com

 

댓글