이펙티브 자바 3판 - 아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라.

김대협·2022년 12월 21일
0

Effective Java 3rd

목록 보기
4/9

아이템 4. 인스턴스화를 막으려거든 private 생성자를 사용하라


정적 메소드와 정적 필드만을 담은 클래스를 사용할 때가 있다.
이는 객체 지향적 사고에 좋은 방식은 아니지만 유틸리티 클래스 등 사용에 쓰임은 분명히 있다.
해당 클래스를 사용 시 인스턴스화를 막아야 하는 문제에 직면한다.

인스턴스 생성을 막는 방식과 그 문제점을 아래에 설명한다.

1) abstract 클래스로 선언하기


abstract 클래스를 선언하면 인스턴스를 직접 생성은 불가하지만 인스턴스화는 막을 수 없는 문제가 있다.

문제점

  • 클래스를 생성하여 상속을 받아 구현 시 문제 발생
  • abstract 선언이 오히려 상속하여 사용하도록 유도하는 의미
public abstract class AbsClass {

    //  클래스의 접근 제어자를 통해 기본으로 생성되었다고 가정할 경우
    public AbsClass() {
        System.out.println( "executed AbsClass Constructor." );
    }

    public static void test() {
        System.out.println( "executed test method." );
    }
}

public class ExtendedAbsClass extends AbsClass {

    // 명시적인 호출이 없더라도 묵시적으로 부모 생성자를 호출
    public ExtendedAbsClass() {
        super();
    }
}

public class AbstractTest {

    public static void doTest() {
        //ExtendedAbsClass absClass = new AbsClass(); // 생성 불가능!
        ExtendedAbsClass extendedAbsClass = new ExtendedAbsClass();
        // 실행 결과: executed AbsClass Constructor.
    }
}

상속 받은 클래스는 생성 시 명시적(Explicit), 묵시적(Implicit) 상황을 막론하고 부모 클래스의 생성자를 호출한다.

2) private 생성자 만들기


private 생성자를 만들면 해당 클래스에서는 만들 수 있는 문제가 있으나, 생성자에서 예외를 throw 해주면 쉽게 해결 된다.

public class PrivateConstructorObj {
    private PrivateConstructorObj() {
        throw new AssertionError();
    }

    public static void main( String[] args ) {
        // private 생성자라도 내부 클래스에서는 접근 가능하다.
        PrivateConstructorObj a = new PrivateConstructorObj(); // error 발생!
    }
}

© 2022.12 Written by Boseong Kim.
profile
기록하는 개발자

0개의 댓글