일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 스프링오류
- SQL
- RDBMS
- 서버
- API
- 오버라이딩
- HTTP
- 스웨거
- 어노테이션
- JPA
- 스프링
- 자바
- application.yml
- Java
- MariaDB
- server
- 스프링시큐리티
- spring
- Swagger
- 의존성주입
- JWT
- 인텔리제이오류
- 스프링RESTAPI
- Static
- 쿼리
- SpringSecurity
- 시큐리티
- 상태코드
- restAPI
- HTTP상태코드
- Today
- Total
취뽀몽
[Java] Private Constructor (private 생성자) 본문
Private 생성자는 싱글톤 패턴에서 주로 봤을 것이다. private 생성자는 특정 클래스의 인스턴스화를 막기 위해 사용된다.
간단히 말해, 클래스 자체가 아닌 다른 위치에서 클래스 인스턴스가 생성되는 것을 방지한다.
public 및 private 생성자를 함께 사용하면 클래스를 인스턴스화하는 방법을 제어할 수 있는데, 이를 생성자 위임이라고 한다.
private 생성자는 해당 클래스 내부에서만 호출 가능하며, 외부에서는 인스턴스를 생성할 수 없다.
여기서, 특정 클래스의 인스턴스화를 막으면 어떤 점이 좋은 것일까?
우선 클래스가 정적 메소드나 상수만을 제공하는 유틸리티 클래스(Utility Class)인 경우, 해당 클래스를 인스턴스화할 필요가 없다.
인스턴스화를 제한함으로써 불필요한 객체 생성을 막아 메모리 사용량을 줄일 수 있다.
또한 스프링에서는 생성자 주입(Costructor Injection)을 사용하는데, 이때 private 생성자를 사용하여 외부에서 클래스를 인스턴스화할 수 없도록 하고 스프링 프레임워크가 인스턴스를 생성하고 주입하는 것을 허용하게 한다.
마지막으로 특정 클래스의 인스턴스화를 제한함으로써 클래스의 동작을 외부에서 조작하는 것을 방지해 보안적인 면에서 효율적이다.
유틸리티 클래스의 예시는 Math와 Arrays가 있는데, 이 클래스들을 살펴보자.
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
/**
* The {@code double} value that is closer than any other to
* <i>e</i>, the base of the natural logarithms.
*/
public static final double E = 2.7182818284590452354;
/**
* The {@code double} value that is closer than any other to
* <i>pi</i>, the ratio of the circumference of a circle to its
* diameter.
*/
public static final double PI = 3.14159265358979323846;
/**
* Returns the trigonometric sine of an angle. Special cases:
* <ul><li>If the argument is NaN or an infinity, then the
* result is NaN.
* <li>If the argument is zero, then the result is a zero with the
* same sign as the argument.</ul>
*
* <p>The computed result must be within 1 ulp of the exact result.
* Results must be semi-monotonic.
*
* @param a an angle, in radians.
* @return the sine of the argument.
*/
public static double sin(double a) {
return StrictMath.sin(a); // default impl. delegates to StrictMath
}
public class Arrays {
/**
* The minimum array length below which a parallel sorting
* algorithm will not further partition the sorting task. Using
* smaller sizes typically results in memory contention across
* tasks that makes parallel speedups unlikely.
*/
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
// Suppresses default constructor, ensuring non-instantiability.
private Arrays() {}
/**
* A comparator that implements the natural ordering of a group of
* mutually comparable elements. May be used when a supplied
* comparator is null. To simplify code-sharing within underlying
* implementations, the compare method only declares type Object
* for its second argument.
*
* Arrays class implementor's note: It is an empirical matter
* whether ComparableTimSort offers any performance benefit over
* TimSort used with this comparator. If not, you are better off
* deleting or bypassing ComparableTimSort. There is currently no
* empirical case for separating them for parallel sorting, so all
* public Object parallelSort methods use the same comparator
* based implementation.
*/
static final class NaturalOrder implements Comparator<Object> {
@SuppressWarnings("unchecked")
public int compare(Object first, Object second) {
return ((Comparable<Object>)first).compareTo(second);
}
static final NaturalOrder INSTANCE = new NaturalOrder();
}
...
두 클래스 모두 생성자를 private로 생성하여 인스턴스화를 막아두었다.
이렇게 기본 생성자를 private로 명시하는 이유는, 다른 생성자가 없다면 자바는 자동으로 기본 생성자를 생성해주기 때문이다.
즉, 이런 기능때문에 의도치않게 인스턴스화를 허용할 수 있게 되는 것이다.
또한 상속을 불가능하게 하는 효과가 있다. private 생성자를 선언함으로써 하위 클래스가 상위 클래스의 생성자에 접근할 수 없다.
public class UtilityClass {
private UtilityClass() { // private 생성자를 만들어 인스턴스화 방지
throw new AssertionError(); // 에러 처리
}
...
}
코드를 작성하고, 생성자가 존재하지만 호출할 수 없으므로 주석으로 부가적인 설명을 하는 것이 좋다.
'java' 카테고리의 다른 글
[JAVA] 불변 클래스 (0) | 2023.06.18 |
---|---|
[Java] JDK와 JRE (0) | 2023.05.13 |
[Java] 동일성과 동등성 (0) | 2023.04.09 |
[Java] String vs StringBuilder vs StringBuffer (0) | 2023.04.07 |
[JAVA] 객체 지향 설계 5원칙 - SOLID (0) | 2023.03.27 |