이것저것
Effective Java [아이템 4 : 인스턴스화를 막으려거든 private 생성자를 사용하라] 본문
Effective Java [아이템 4 : 인스턴스화를 막으려거든 private 생성자를 사용하라]
[모든 클래스가 인스턴화가 필요한 것은 아니다.]
정적 메서드와 필드만을 담을 클래스는 쓸모가 있다. java.lang.Math, java.util.Array 처럼 기본 타입값이나 배열에 관련된 메서드들을 모을 수 있고, java.util.Collections 처럼 특정 인터페이스 구햔 객체를 생성해주는 메서드를 모아 놓을 수도 있다.
final 클래스와 관련된 메서드를 모을 때도 마찬가지다. 이를 상속하여 하위클래스에 메서드를 넣는 것이 불가능하기 때문이다. (애초에 상속 불가능)
[인스턴스화를 막으려면?]
클래스 내부에 정적 메서드만 있고, 유틸리티 기능을 강조하기 위한 클래스를 하나 만들어보았다.
유틸리티 클래스
- 인스턴스 메서드와 인스터스 변수를 일절 제공하지 않고, 정적 메서드와 변수만을 제공하는 클래스를 뜻한다.
- 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계한 게 아니다.
- 클래스 본래의 목적인 '데이터와 데이터 처리를 위한 로직의 캡슐화'를 실행하는 것이 아닌,'비슷한 기능의 메서드와 상수를 모아서 캡슐화'한 것이 유틸리티 클래스이다.
public class DateUtility {
private static String FULL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
// 생성자 없음
public static String convertDateToString(Date date) {
return new SimpleDateFormat(FULL_DATE_FORMAT).format(date);
}
}
(컴파일러는 생성자를 명시하지 않는 경우에, 자동으로 기본 생성자 생성)
public void someMethod() {
// 이렇게 사용하길 기대했으나!
DateUtility.convertDateToString(new Date());
// 누군가는 이렇게 사용할 수도
DateUtility dateUtility = new DateUtility();
String formattedToday = dateUtility.convertDateToString(new Date());
}
이런 인스턴스화를 막기 위해 private 생성자를 추가해주면 된다.
class DateUtility {
private DateUtility() {
/**
* 클래스 내부에서도 호출이 안되도록 막는다.
*/
throw new AssertionError(); //행여나 클래스 내부에서 실수로라도 생성를 호출하는 것을 막기 위해
}
// 생략
}
public class PrivateConstructorTest {
public static void main(String[] args) {
// DateUtility() has private access in DateUtility
DateUtility dateUtility = new DateUtility();
}
}
생성자를 private으로 만들면, 외부에 공개하지 않기 때문에 상속도 불가능해진다.
즉 private 생성자를 추가함으로써, 클래스의 인스턴스화를 막을 수 있다.
'Effective Java' 카테고리의 다른 글
Effective Java [아이템 3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라] (0) | 2021.04.17 |
---|---|
Effective Java [아이템 2 : 생성자에 매개변수가 많다면 빌더를 고려하라] (0) | 2021.04.17 |
Effective Java [아이템 1 : 생성자 대신 정적 팩터리 메서드를 고려하라] (0) | 2021.04.17 |
Comments