- 시스템 객체나 Connection 객체는 싱글톤임을 보장하라!
System관련 객체, 또는 DB connection을 관리하는 JDBC 같은 객체는 전체 프로그램에 하나의 인스턴스만 존재함을 보장하여야 한다.
바로 생성자를 private으로 만들어 싱글톤클래스를 설계할 수 있다.
public class test{
public static final test INSTANCE = new test();
private test() {}
...
}
위와 같이 클래스를 설계하면 생성자가 private이기 때문에 INSTANCE를 초기화할 때가 아니면 바깥에서 생성자를 호출 할 방법이 없다! 또는 INSTANCE를 private으로 선언하고 getter 를 static method로 선언하여 사용하는 방법 도 있다.
위의 경우 리플렉션 API를 사용하면 생성자를 호출할 수 있기 때문에 두 번째 객체가 생성될 때 Exception을 throw하도록 처리해주어야 한다.
또는 열거 타입(enum)을 사용하는 방법 도 있는데
public enum test {
INSTANCE;
...
}
간결하고 추가 노력 없이 직렬화 가능한 싱글턴 객체를 만들 수 있다.
2. 정적 메서드, 필드만 제공하려면 private 생성자를 이용하라!
private 생성자를 일부러 선언해 놓으면 public 생성자를 컴파일러가 생성하지 않기때문에, 이 객체를 new를 통해 인스턴스화 할 방법이 없어진다. 대신 private으로 선언하면 하위객체에서 해당 생성자를 부를 수 없기 때문에 상속이 불가능해진다.
3. 불필요한 객체 생성은 피하자!
3.1 오토박싱은 최대한 사용을 피하자!
오토박싱이란 기본타입과 박싱된 기본타입을 상호 변환해주는 기술인데 잘못 사용하면 엄청난 결과를 초래한다 다음 코드를 보자
Long sum = 0L;
for (long i = 0 ; i <= Integer.MAX_VALUE ; i++){
sum += i;
}
위의 경우 sum이 Long이기 때문에 long 변수인 i를 더할때마다 불필요한 객체가 계속 만들어지고 이들은 가비지컬렉션의 대상이 된다. 엄청난 오버헤드다.
3.2 다 쓴 객체는 참조를 해제하라!
보통의 경우 다 쓴 변수는 스코프 밖으로 밀어내기만 하면 가비지컬렉팅의 대상이 된다 하지만 직접 메모리를 관리하는 클래스의 경우 ‘다 쓴 참조’를 주의하라!
private Object[] elements;
public Object pop() {
if (size == 0) throw EmptyStackException();
return elements[--size];
위의 경우 더 이상 pop된 객체는 사용되지 않지만, 참조가 남아있기 때문에 가비지컬렉팅이 되지 않는다. 이 경우 elements[size] = null로 명시해주어야 한다.