-
[Effective Java] Item 4. 인스턴스화를 막으려거든 private 생성자를 사용하라Java/Effective Java 2020. 8. 13. 23:50반응형
private 생성자의 사용
- java.lang.Math와 java.util.Arrays 처럼 기본 타입 값이나 배열 관련 메서드를 모아놓을 수 있습니다.
- java.util.Collections 처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(혹은 팩토리)를 모아놓을 수도 있습니다. (자바 8부터는 이런 메서드를 인터페이스에 넣을 수 있습니다.)
- final 클래스와 관련한 메서드들을 모아놓을 때 사용합니다.
이러한 정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계하는게 아닙니다. 하지만 생성자를 명시하지 않으면 컴파일러가 자동으로 디폴트 생성자를 만들게 됩니다. 이러한 사실은 사용자에게는 생성자 자동 생성된 것인지 구별할 수 없게 합니다.
인스턴스화를 막기 위해서 추상 클래스를 생각할 수 있지만 추상 클래스로 만드는 것으로는 인스턴스화를 막을 수 없습니다. 추상 클래스는 하위 클래스를 만들어 인스턴스화 할 수 있기 때문입니다. 이를 본 사용자는 상속하여 쓰라는 뜻으로 오해할 수 있습니다.
인스턴스 생성을 막는 방법
인스턴스 생성을 막는 방법은 private 생성자를 추가하면 클래스의 인스턴스화를 쉽게 막을 수 있습니다. 명시적 생성자가 private 이니 클래스 바깥에서는 접근할 수 없습니다. 클래스 안에서 실수로라도 생성자를 호출하지 않도록 생성자 안에서 Assertion Error 를 던지면 실수를 줄 일 수 있습니다.
public class UtilityClass { // 기본 생성자가 만들어지는 것을 막는다(인스턴스화 방지용). private UtilityClass() { throw new AssertionError(); } // 나머지 코드.. }
위 코드는 어떤 환경에서도 클래스가 인스턴스화되는 것을 막아줍니다. 또한 적절한 주석을 통해 생성자가 존재하지만 호출할 수 없다는 점에 직관성을 부여하는 것이 좋습니다. 이 방식은 생성자의 접근 지정자가 private 이므로 상속을 불가능하게 하는 효과도 있습니다.
참고자료
반응형'Java > Effective Java' 카테고리의 다른 글
[Effective Java] Item 6. 불필요한 객체 생성을 피하라 (0) 2020.08.16 [Effective Java] Item 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) 2020.08.14 [Effective Java] Item 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) 2020.08.12 [Effective Java] Item 2. 생성자에 매개변수가 많다면 빌더를 고려하라 (0) 2020.08.11 [Effective Java] Item 1. 생성자 대신 정적 팩토리 메소드를 고려하라 (0) 2020.08.09