때로는 정적 메서드나 필드만 모은 클래스를 만들고 싶을 때가 있다. 자바의 기본 자료형 값 또는 배열에 적용되는 메서드를 한군데 모아둘 때 유용하다. java.lang.Math나 java.util.Arrays가 좋은 예다.특정 인터페이스를 구현하는 객체를 만드는 팩터리 메서드 등의 정적 메서드를 모아놓을 때도 사용할 수 있다. java.util.Collections는 그 좋은 예다.
이런 유틸리티 클래스들은 객체를 만들 목적의 클래스가 아니다. 객체를 만들면 이상하다. 하지만 생성자를 생략하면 컴파일러는 자동으로 인자 없는 public 기본 생성자를 만들어 버린다. 사용자는 이 생성자를 일반 생성자와 구별할 수 없다. 따라서 원래 의도와는 달리 객체 생성이 가능한 클래스가 공개 API에 포함되느 일도 드물지 않다.
객체를 만들 수 없도록 하려고 클래스를 abstract로 선언해 봤자 소용없다. 하위 클래스를 정의하는 순간 객체 생성이 가능해지기 때문이다. private 생성자를 클래스에 넣어 객체 생성을 방지하자.
1 2 3 4 5 6 7 8 | class UtilityClass { private UtilityClass() { throw new AssertionError(); }; //나머지는 생략 } |
명시적으로 정의된 생성자가 private이므로 클래스 외부에서는 사용할 수 없다. AssertionError는 반드시 필요한 것은 아니지만, 클래스 안에서 실수로 생성자를 호출하면 바로 알 수 있게 하기 위한 것이다. 또한 위와 같이 하면 하위 클래스도 만들 수 없다. 모든 생성자는 상위 클래스의 생성자를 명시적으로든 아니면 묵시적으로든 호출할 수 있어야 하는데, 호출 가능한 생성자가 상위 클래스에 없기 때문이다.
'Effective Java > 1장 객체의 생성과 삭제' 카테고리의 다른 글
Effective Java #6 유효기간이 지난 객체 참조는 폐기하라 (0) | 2018.10.20 |
---|---|
Effective Java #5 불필요한 객체는 만들지 마라 (0) | 2018.10.20 |
Effective Java #3 private 생성자나 enum 자료형은 싱글턴 패턴을 따르도록 설계하라 (0) | 2018.10.18 |
Effective Java #2 생성자 인자가 많을 때는 빌더 패턴 적용을 고려하라 (0) | 2018.10.17 |
Effective Java #1 생성자 대신 정적 팩토리 메서드를 사용할 수 없는지 생각해 보라 (0) | 2018.10.16 |