(Effective Java 2/E) 105. Item 5 - Avoid creating unnecessary objects

Avoid creating unnecessary objects

  • 2판 제목 : 불필요한 객체는 만들지 말라
  • 3판 제목 : 불필요한 객체 생성을 피하라

기능적으로 동일한 객체는 필요할때마다 생성하는 것보다 재사용하는 것이 좋을 때가 많다.

특히 불변 객체는 언제나 재사용할 수 있다.

안 좋은 예시를 하나 살펴보자.

1
String s = new String("effective");

“effective” 문자열 자체로 String 객체이므로 위와 같이 호출하면 계속해서 불필요한 객체를 생성하는 셈이다.

1
String s = "effective";

따라서 위와 같이 처리하는 것이 바람직하다.

물론 변경가능한 객체라도 재사용하는 것이 가능하다.

다만, 주의해야할 점이 몇 가지있다.

1. 생성 비용이 높은 경우

생성 비용이 높은 객체를 계속해서 생성하는 경우의 예제를 보자.

1
2
3
4
5
6
7
8
9
10
public class Scheduler {
private Date currentDate;

public boolean isBirthDay() {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(1989, Calendar.DECEMBER, 10);
Date date = cal.getTime();
return currentDate.compareTo(date);
}
}

Scheduler 클래스의 isBirthDat 함수는 호출할 때마다 Calendar, TimeZone, Date 객체를 하나씩 생성하고 있다.

이렇게 생성 비용이 높은 객체를 거듭 생성하는 경우 별도의 정적 초기화 블록(static initializer) 를 통해 개선하는 것이 좋다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Scheduler {
private Date currentDate;
private static final Date birthDay;

static {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(1989, Calendar.DECEMBER, 10);
birthDay = cal.getTime();
}

public boolean isBirthDay() {
return currentDate.compareTo(birthDay);
}
}

위와 같이 개선하면 isBirthDay 함수를 여러번 호출해도 최초 호출 한 번만 객체를 생성하게 된다.

2. 자동 객체화를 수행하는 경우

JDK 1.5부터 컴파일러는 자동 객체화(autoboxing) 를 지원해준다.

자동 객체화를이용해 기본 자료형과 해당 자료형의 포장 클래스간의 형변환이 자동으로 이루어진다.

예제를 살펴보자.

1
2
3
4
5
6
7
public int sumLong() {
Long result = 0L;
for (long i = 0 i < Integer.MAX_VALUE; i++) {
result += i;
}
return result;
}

일단 이 코드는 정상 동작하긴 한다.

문제는 resulti의 연산을 위해 longLong으로 계속해서 형변환을 수행한다.

따라서 Integer.MAX_VALUE의 값인 2의 31제곱만큼 Long 객체를 생성하게 된다.

따라서 기본 자료형을 주로 사용하되, 생각지도 못한 자동 객체화가 발생하지 않도록 주의해야 한다.