인스턴스화를 막으려면 private 생성자를 사용하라
인스턴스화를 막아야 하는 경우
유틸 클래스를 만들 때
java.lang.Math
,java.util.Arrays
,java.util.Collections
와 같은 유틸 클래스를 구성하는 경우에는 해당 클래스가 쓸데없이 인스턴스화 되는 것을 막아야 한다.- 객체지향적으로는 곱게 보이지 않을 수 있는 사용방식이다.
유틸 클래스 용도 1: 특정 인터페이스를 구현하는 객체 생성 팩토리 메서드를 모아놓는다.
// from Collections 클래스
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
Map
인터페이스 타입 객체를 넣으면,SynchronizedMap
을 반환해주는 정적메서드의 예이다.- 사실 자바8부터는 이러한 메서드를 인터페이스에 몰아놓을 수도 있다.
- 인터페이스에 몰아넣으면 인스턴스화 걱정은 필요 없다.
유틸 클래스 용도 2: 특정 타입을 이용하는 특수한 메서드들을 모아놓는다.
// from Collections 클래스
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
- 무언가 객체를 생성하진 않는다. 하지만
Comparable
을 구현한 제너릭 타입을 사용하는List
를 정렬해주는 기능이 있다. Collections
는 어찌됐거나 인스턴스화 하라고 만든 클래스는 아니다.
유틸 클래스 용도 3: final
클래스와 관련된 메서드들을 모아놓는다.
final
클래스를 상속해 하위 클래스에 메서드를 넣는 것은 불가능하기 때문에 특정 클래스 내부에 몰아넣고final
클래스와 함께 쓴다.
추상 클래스로는 인스턴스화를 막을 수 없다.
- 추상 클래스의 경우 상속하여 하위 클래스를 만들면 인스턴스화가 된다.
- 사용자는 해당 추상 클래스를 상속하여 쓰라는 의도로 오해할 수 있는데 이러면 더 큰 문제가 된다.
private 생성자로 인스턴스화를 막을 수 있다.
- 컴파일러가 기본 생성자를 만드는 때는 오직 명시된 생성자가 없을 때 뿐이다.
- 고로
private
생성자를 만듦으로써 명시된 생성자가 생기므로 기본 생성자가 생기지 않는다.
- 고로
public class Collections {
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
}
}
- 자바의 대표 API인
Collections
의 구현을 살펴보면, 위와 같이 생성자를private
으로 막아 인스턴스화를 금지시켰다. - 이는 상속을 막기도 한다.
- 객체를 상속하는 경우
super()
를 이용하여 상위 클래스의 생성자를 호출해야 하는데private
접근 제어자는 외부에서 접근이 불가능하다.
- 객체를 상속하는 경우
좀 더 확실히 막기
public class Collections {
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
throw new AssertionsError();
}
}
- 위와 같이 막으면, 만일 리플렉션으로 접근해도 예외가 터질 것이다.
반응형
'Java > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바, 쉽게 정리하기 - item6. 불필요한 객체 생성을 피하라 (0) | 2021.12.26 |
---|---|
이펙티브 자바, 쉽게 정리하기 - item5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2021.12.25 |
이펙티브 자바, 쉽게 정리하기 - item3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2021.12.24 |
이펙티브 자바, 쉽게 정리하기 - item2. 생성자에 매개변수가 많다면, 빌더 패턴을 고려하라 (0) | 2021.12.23 |
이펙티브 자바, 쉽게 정리하기 - item1. 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2021.12.22 |