📕🐘 도로락 - 코끼리를 냉장고에 넣는 방법
자바[Java] | 2019. 7. 16. 11:27

[Effective Java] 인스턴스화가 필요없는 Utility 클래스 등은 private 생성자를 사용하자

인스턴스화가 필요없는 Utility 클래스 등은 private 생성자를 사용하자

프로젝트를 진행할 때 어플리케이션 전역에서 사용하는 기능의 공통 메서드들은 보통 static 멤버로만 이루어진 Utility 클래스로 만들어 사용하곤 합니다. 예를 들자면 문자열을 조작할 때 사용하는 StringUtil이라거나 DateUtil 등이 있습니다.

예를 들면 org.apache.commons 라이브러리에도 StringUtils가 존재합니다.

public class StringUtils {

    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    public static boolean contains(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        return str.indexOf(searchStr) >= 0;
    }

    ..생략..

}

그런데 이런 static 멤버만 있는 클래스는 굳이 new 키워드를 통해 의미없이 인스턴스화 할 필요가 없습니다. 메모리만 낭비할 뿐이며, 그런 코드를 보는 다른 사용자들 또한 오해하여 인스턴스화 해서 사용할 가능성도 있습니다. 또한 개인적으로 Util 클래스는 인스턴스를 생성하지 않고 사용하는 맛(?)도 하나의 즐거움이라고 생각합니다. 코드상에서도 더욱 깔끔해 보이는 점도 있는데, Util 클래스를 사용할 때마다 인스턴스화 하는 코드가 필요하다면 가독성에도 좋지 못할 것입니다.

String emptyStr = "";

StringUtils utils = new StringUtils(); //인스턴스화 하여 사용하는 경우
utils.isEmpty(emptyStr);

StringUtils.isEmpty(emptyStr); //인스턴스화 하지 않고 사용하는 경우

해결법

Java 컴파일러는 우리가 기본생성자를 구현하지 않는 경우 컴파일 과정에서 자동으로 생성해주는데, Util 클래스를 사용하는 다른 사용자들이 이를 보고 오해하여 사용할 수 있습니다. 따라서 인스턴스화를 막고 싶다면 기본생성자를 명시적으로 선언하는 대신 접근제한자를 private으로 설정해주면 됩니다.

public class StringUtils {

    /**
     *  인스턴스화 하지 않고 사용
     */
    private StringUtils() {
        throw new InstantiationException();
    }

기본생성자가 private이기 때문에 인스턴스화 할 수 없으며, 상속을 하지 못하게 하는 효과도 있습니다. (하위 클래스에서는 무조건 상위 클래스의 생성자를 호출해야 하므로)

여기서 private으로 생성자를 만드는 것에 그치지 않고 예외까지 던지는 이유는 Util 클래스 내부에서도 생성자를 사용하지 못하도록 한다는 의도를 알리기 위함입니다.

도로락

도로락

Writer

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그