개발을 하다 보면 정적 메서드와 정적 필드만을 담은 클래스를 만들 때가 있다.
java.lang.Math와 java.util.Arrays처럼 기본 타입 값이나 배열 관련 메서드들을 모아 놓을 수 있다.
//Math 메서드
public final class Math {
private Math() {}
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
public static double sin(double a) {
return StrictMath.sin(a); // default impl. delegates to StrictMath
}
...
...
...
}
//Arrays 메서드
public class Arrays {
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
private Arrays() {}
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 static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > arrayLength) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}
}
또한 java.util.Collections 처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드를 모아놓을 수도 있다.
마지막으로 final 클래스와 관련한 메서드들을 모아놓을 때도 사용한다. (Math 클래스도 final 클래스이다. final 클래스는 하위 클래스에서 상속이 불가능함)
정적 멤버만 담은 클래스는 인스턴스로 만들어 쓰려고 설계한 것이 아니다.
그러나 컴파일러가 자동으로 기본 생성자를 만들게된다. 사용자는 이 생성자가 자동 생성된 것인지 구분할 수 없다.
인스턴스화를 막는 방법
위와 같은 클래스를 추상 클래스로 만드는 것으로는 인스턴스화를 막을 수 없다. 하위 클래스를 만들어 인스턴스화를 할 수 있기 때문이다.
인스턴스화를 막는 방법은 간단하다. private 생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다.
public class NoInstance {
//인스턴스화 방지용
private NoInstance(){
throw new AssertionError();
}
public static void print(){
System.out.println("PRINT");
}
}
public class GoMain {
public static void main(String[] args) {
// 인스턴스화 불가능
NoInstance noInstance = new NoInstance();
noInstance.print();
}
}
명시적 생성자가 private 이므로 클래스 바깥에서는 접근할 수 없다. 또한 클래스 안에서 실수로라도 생성자를 호출하지 않게 AssertionError를 던지도록 한다.
이 방식은 상속을 불가능하게 하는 효과도 있다. 같은 팀 개발자를 위해 위의 코드처럼 주석을 통해 가이드할 수 있도록 하자.
'Study > Effective Java' 카테고리의 다른 글
[아이템07] 다 쓴 객체 참조를 해제하라 (0) | 2022.09.30 |
---|---|
[아이템05] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2022.09.22 |
[아이템03] private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2022.09.08 |
[아이템02] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2022.08.22 |
[아이템01] 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2022.08.19 |