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

1 minute read

이펙티브 자바를 공부한 내용입니다.


인스턴스화를 막으려거든 private 생성자를 사용하라

간혹 정적 필드나 정적 메서드만을 담은 클래스를 만드는 경우가 있다.
이러한 유틸리티 클래스는 인스턴스를 만들어서 사용하기 위한 클래스가 아니다.
상수 모음이나, 팩토리가 될 수도 있다.
자바에서 사용되는 클래스는 java.lang.Math, java.util.Collections와 같은 클래스가 있다.


인스턴스화를 막는 방법

인스턴스를 생성은 new 키워드를 사용해 Heap 영역에 메모리 공간을 할당하고,
메모리 공간의 주소를 반환한 후 생성자를 실행시킨다.

이때 private 생성자만을 만들어둔다면 인스턴스 생성을 막을 수 있다.
예외를 꼭 던질 필요는 없지만, 혹여나 내부에서 사용할 수 있으므로 예외를 사용한다.

public class UtilityClass {
    
    private UtilityClass() {
        throw new UnsupportedOperationException();
    }

}

주의사항

자바에서 클래스를 만들기 위해서는 필수적으로 생성자가 필요하다.
하지만 생성자가 없는 클래스도 수두룩하다.

생성자가 없는 클래스는 컴파일러가 기본 생성자를 만들어준다.
기본 생성자는 아무런 매개변수를 받지 않는 public 생성자이다.

error

javap를 통해 바이트코드를 확인해보았다.
빨간색 네모 표시를 보면 기본 생성자가 만들어져 있는 것이 보인다.

error

인텔리제이 기능으로 class 파일을 열면 디컴파일된 소스가 보인다.
소스에는 기본 생성자가 없지만 class 파일엔 기본 생성자가 있다.

이처럼 컴파일러는 기본 생성자를 만들어주고,
public 생성자가 있다면 인스턴스를 생성할 수 있기 때문에 주의해야한다.


또 추상 클래스의 인스턴스 생성을 할 수 없으니,
추상 클래스를 만드는 방법을 떠올릴 수 있으나, 이것으로는 인스턴스화를 막을 수 없다.
오히려 API 사용자는 상속을 받아 사용하라는 의미로 받아들일 것이고,
하위 클래스가 있다면 인스턴스를 만들 수 있다.


마지막으로 private 생성자를 사용할 경우 상속을 불가능하게 한다.
모든 생성자는 명시적으로든 묵시적으로든 상위클래스의 생성자를 호출하게 되는데,
상위 클래스의 생성자가 private으로 선언되어있으니,
하위 클래스에서 상위 클래스의 생성자를 호출 할 수 없기 때문이다.


참조자료

Java Bytecode
https://d2.naver.com/helloworld/1230

Tags:

Categories:

Updated:

Leave a comment