상세 컨텐츠

본문 제목

[이펙티브 자바] Item 3. private 생성자나 열거타입으로 싱글턴임을 보증하라 | 2장

Development Study/이펙티브 자바

by yooputer 2023. 3. 29. 09:42

본문

이펙티브 자바 2장 Item3을 요약한 내용입니다.


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

 

싱글턴을 만드는 방법에는

public static final 필드를 이용하는 방법

정적 팩터리 메서드를 구현하는 방법

원소가 하나인 enum 타입으로 구현하는 방법이 있다.

 


public static final 필드를 이용하는 방법의 예제는 아래와 같다.

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

 

생성자가 private이기 때문에 외부에서 호출할 수 없고 Elvis.INSTANCE를 초기화할 때 딱 한번만 실행된다.

 

이 방식의 장점은 해당 클래스가 싱글턴임이 명확하고 코드가 간결하다는 것이다.

하지만 AccessibleObject.setAccessible을 이용해 private 생성자를 호출하는 리플렉션 공격이 발생할 수 있기 때문에 생성자를 수정하여 두번째 객체가 생성되려 할 때 예외를 던지게 만들어야 한다.


정적팩터리 메서드를 이용하는 방법의 예제는 아래와 같다.

public class Elvis {
	private static final Elvis INSTANCE = new Elvis();
    	private Elvis(){...}
    	public static Elvis getInstance() {return INSTANCE;}
}

 

이 방식의 장점은 정적팩토리 메서드를 유연하게 수정할 수 있다는 것이다.

또한 정적팩터리의 메서드 참조를 공급자(supplier)로 사용할 수 있다.

하지만 클래스를 직렬화하고 역직렬화할 때마다 새로운 인스턴스가 생성되기 때문에 아래와 같이 readResolve 메서드를 추가해야 한다.

(public static final 필드를 이용하는 방법도 마찬가지다)

private Object readResolve(){
	return INSTANCE;
}

원소가 하나인 enum 타입으로 구현하는 방법의 예제는 아래와 같다.

public enum Elvis {
	INSTANCE;
}

 

이 방식은 더 간결하고, 직렬화문제나 리플렉션 공격에도 자유롭다.

싱글턴을 만드는 가장 좋은 방법이다.

하지만 다른 클래스를 상속해야 하는 경우에는 이 방법을 사용할 수 없다.

관련글 더보기