View
정적 메서드, 정적 필드를 가지는 유틸리티 클래스
개발을 하다 보면 유틸리티 클래스가 필요한 경우가 있다.
이러한 도구용 클래스는 단순히 정적 메서드와 정적 필드만을 담은 클래스로써 객체 지향과는 거리가 멀지만 분명 쓸모가 있다.
예시로는 java.lang.Math와 java.util.Arrays가 있다.
Math 클래스는 계산과 관련된 정적 메서드와 상수들을 담고 있고, Arrays 클래스는 배열과 관련된 정적 메서드를 담고 있다.
이러한 유틸리티 클래스는 인스턴스화를 위해 설계된 클래스가 아니기 때문에 두 클래스 모두 private 생성자를 가지는 것을 볼 수 있다.
private 기본 생성자를 명시하는 이유
그렇다면 왜 기본 생성자를 private으로 명시해주는 것일까?
그 이유는 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 만들기 때문이다. 즉, 매개변수를 받지 않는 public 생성자가 만들어지고, 의도치 않게 인스턴스화를 허용할 수 있게 된다.
아래의 예시는 String으로 입력된 값을 split하고 List<Integer>형태로 변환해주는 유틸 클래스이다.
이 클래스를 컴파일해보면 다음과 같이 public 기본 생성자가 자동으로 생성된 것을 볼 수 있다.
인스턴스화를 위해 설계된 클래스가 아님에도 인스턴스화를 할 수 있게 된 것이다.
이를 방어하기 위해 기본 생성자를 private로 명시해주면,
기본 생성자가 private로 생성된 것을 볼 수 있다. 이제 클래스 바깥에서는 해당 클래스에 접근할 수 없다.
핵심 정리
추상클래스는 인스턴스화가 불가능하기 때문에 인스턴스화를 막기 위한 방법으로 추상 클래스를 떠올릴 수 있다.
하지만 인스턴스화를 막기위해 추상 클래스를 만든다면, 오히려 더 큰 문제가 될 수 있다.
사용자 입장에서 추상 클래스를 보고 상속하여 사용하라는 의미로 받아들일 수 있기 때문이다.
그러니 인스턴스화를 막으려면 위에 설명한 방법처럼 private 생성자를 명시해 생성자 방어를 해줘야 한다. 그리고 주석을 통해 생성자 역할에 대한 직관성을 높이고, 더 신경 쓴다면 AssertionError를 에러를 던져주자.
AsserrtionError - 선언이 실패한 것을 나타내는 에러
'BackEnd > 이펙티브 자바' 카테고리의 다른 글
[이펙티브 자바] Item6- 불필요한 객체 생성을 피하라 (2) | 2020.12.12 |
---|---|
[이펙티브 자바] Item5- 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2020.11.22 |
[이펙티브 자바] Item3- private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2020.11.14 |
[이펙티브 자바] Item2- 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2020.11.07 |
[이펙티브 자바] Item1- 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2020.10.29 |