객체지향임에도 불구하고 간혹 인스턴스를 생성하지 말라고 권장하는 케이스가 있습니다.
보통 static 한 메서드들만 가지고 있는 유틸성 클래스가 위 케이스에 해당합니다.
인스턴스화를 막는 방법은 아래와 같이 두 가지가 있습니다.
- private 생성자를 통해 인스턴스화 방지
- abstract 클래스로 생성하여 인스턴스화 방지
- 이 방법은 상속을 통해 우회적으로 생성자를 호출할 수 있으므로 불완전한 방법
방법 1. private 생성자를 통해 인스턴스화 방지
public 혹은 protected 생성자 없이 private 생성자만 정의할 경우 같은 클래스 내 main 함수에서 호출하지 않는 이상 생성자를 호출할 수 없어 인스턴스화를 방지할 수 있습니다.
같은 클래스 내 main 함수에서도 호출하는 것을 방지하고 싶을 경우 private 생성자 호출 시 AssertionError()를 반환하도록 처리하면 됩니다.
생성자를 private 접근 지시자로 선언했기 클래스 외부에서 생서자를 호출하는 것은 방지할 수 있었습니다.
하지만 여전히 클래스 내에서는 생성자를 호출할 수 있었습니다.
이를 방지하기 위해서는 앞서 언급했다시피 private 생성자 호출 시 AssertionError()를 반환하도록 처리하면 됩니다.
스프링 프레임워크에서는 유틸리티 클래스들을 대부분 두 번째 방법인 추상 클래스로 선언했지만 Collections과 같은 유틸성 클래스는 첫 번째 방법을 사용한 것을 확인할 수 있습니다.
마지막으로 Collections 클래스처럼 인스턴스화가 불가한 이유를 주석으로 작성해 주는 것을 습관화하면 좋을 것 같습니다.
방법 2. abstract 클래스로 생성하여 인스턴스화 방지
스프링 프레임워크의 유틸성 클래스는 대부분 해당 방법을 사용했는데 추상 클래스 자체는 인스턴스화할 수 없지만 해당 클래스를 상속하는 서브 클래스는 인스턴스화할 수 있다는 단점이 있습니다.
AnnotationConfigUtils도 스프링에서 제공하는 유틸성 클래스인데 두 번째 방법을 사용한 것을 확인할 수 있습니다.
이 클래스 또한 제가 굳이 상속을 해서 생성자를 호출할 경우 인스턴스화를 방지하지 못하는 것을 확인할 수 있습니다.
정리
인스턴스화 방지를 위해 추상 클래스를 구현하는 것보다는 private 생성자를 사용하는 방법이 더 효과적입니다.
참고
이펙티브 자바
이펙티브 자바 완벽 공략 1부 - 백기선 강사님
'JAVA > Effective Java' 카테고리의 다른 글
[아이템 6] 불필요한 객체 생성을 피하라 (0) | 2024.01.21 |
---|---|
[아이템 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2024.01.20 |
[아이템 3] private 생성자나 열거 타입으로 싱글턴임을 보증하라 (2) | 2024.01.19 |
[아이템 2] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2024.01.18 |
[아이템 1] 생성자 대신 정적 팩토리 메서드를 고려하라 (0) | 2024.01.16 |