장쫄깃 기술블로그

[Java] static method만 있는 유틸리티 클래스에 private 생성자를 사용해야 하는 이유 본문

Programming Language/Java

[Java] static method만 있는 유틸리티 클래스에 private 생성자를 사용해야 하는 이유

장쫄깃 2024. 8. 2. 10:56
728x90


들어가며


Add a private constructor to hide the implicit public one

 

유틸리티 클래스(UtilClass)를 만들다 보면 sonar에서 위와 같은 경고 문구를 보여주는 경우가 있다. 영문 그대로 해석해 보면 public 생성자를 숨기기 위해 private 생성자를 추가하라고 한다. 실제로 private 생성자를 추가하면 경고가 사라진다. 이 경고는 왜 발생하고, 어떻게 해결해야 하는지에 대해 알아보도록 하겠다.

 

 


유틸리티 클래스란?


유틸리티 클래스는 보통 객체 상태를 가지지 않고, 공용(static) 메소드를 제공하여 여러 곳에서 재사용할 수 있는 기능들을 모아놓은 클래스를 말한다.

 

UtilityClass

public class UtilityClass {

    public static void utilityMethod() {
        // 유틸리티 메소드 구현
    }
    
}

 

UtilityClass 사용

public class Main {

    public static void main(String[] args) {
        UtilityClass.utilityMethod();
    }
    
}

 

예를 들어, 수학 연산에 대한 여러 정적 메소드를 제공하는 Java의 java.lang.Math 클래스가 있다.

public class Main {

    public static void main(String[] args) {
        Math.abs(-10);
        Math.random();
    }
    
}

 

 


private 생성자 사용


유틸리티 클래스는 객체 상태를 가지지 않기 때문에 인스턴스화할 필요가 없다. 오히려 인스턴스화되는 것을 방지하여 의도하지 않은 메모리 사용과 불필요한 객체 생성으로 인한 혼란을 피할 수 있다.

 

유틸리티 클래스의 인스턴스화를 방지하기 위해 private 생성자를 사용하는 방법이 있다. private 생성자는 외부에서 해당 클래스의 인스턴스를 생성할 수 없도록 한다.

 

private 생성자를 사용하면 다음과 같은 효과를 가진다.

인스턴스화 방지

  • 클래스의 인스턴스 생성을 명시적으로 방지하여, 해당 클래스가 인스턴스화될 필요가 없다는 의도를 명확히 한다.

 

코드의 명확성

  • 이 클래스는 인스턴스화할 필요가 없다는 것을 다른 개발자들에게 명확히 알릴 수 있다.

 

안전성

  • 잘못된 인스턴스화를 방지하여 메모리 낭비와 같은 문제를 예방할 수 있다.

 

 


private 생성자 사용 방법


private 생성자를 사용하는 방법은 다음과 같다.

 

1. private 생성자 직접 생성

private 생성자를 직접 작성한다.

public class UtilityClass {

    // private 생성자
    private UtilityClass() {
        throw new UnsupportedOperationException("Utility class");
    }

    public static void utilityMethod() {
        // 유틸리티 메소드 구현
    }
    
}

 

2. Lombok의 @NoArgsConstructor(access = AccessLevel.PRIVATE) 사용

Lombok 라이브러리를 사용하면, @NoArgsConstructor(access = AccessLevel.PRIVATE) 어노테이션을 통해 클래스의 기본 생성자를 private으로 설정할 수 있다.

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class UtilityClass {

    public static void utilityMethod() {
        // 유틸리티 메소드 구현
    }
    
}

 

3. Lombok의 @UtilityClass 사용

Lombok의 @UtilityClass 어노테이션은 유틸리티 클래스를 만들 때 매우 유용한 어노테이션이다. 이 어노테이션을 클래스에 적용하면 그 클래스를 유틸리티 클래스로 간주하고, 다음과 같은 작업을 자동으로 수행한다.

  1. 자동으로 private 생성자를 생성하여 클래스의 인스턴스화 방지
  2. 클래스 내의 모든 메소드를 자동으로 static으로 생성
  3. 클래스 내의 모든 필드를 자동으로 static으로 생성
@UtilityClass
public class UtilityClass {

    public void utilityMethod() {
        // 유틸리티 메소드 구현
    }
    
}

 

해당 코드에서 UtilityClass의 private 생성자를 자동으로 생성하고, utilityMethod는 자동으로 static으로 선언된다.

 

 


결론


유틸리티 클래스를 사용할 때 private 생성자를 사용하면 인스턴스화를 방지하고, 클래스의 의도를 명확히 하며, 코드의 안정성을 높일 수 있다. 유틸리티 클래스 설계 시 따라야 할 좋은 관행 중 하나라고 생각한다.

 

728x90