규칙 6. 불필요한 객체 생성을 피하라
규칙 5. 불필요한 객체는 만들지 말라
-
변경 불가능(immutable) 객체는 언제나 재용사할수 있다.([규칙 15](#item15))
-
Bad Practice 코드는 실행될 때마다
String
객체를 만드는 쓸데없는 짓을 한다. loop 도는 만큰String
객체를 생성한다. *Good Practices*는 실행할 때마다 객체를 생성하지 않고, 동일한String
객체를 사용한다. 같은 가상머신에서 실행되는 모든 코드가 해당 객체를 사용한다([JLS, 3.10.5](https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.5)).```java for(int i = 0; i < 999999; i++) { // Bad Practice System.out.println(new String("test"));
// Good Practice System.out.println("test"); } ```
-
Static Factory Method([규칙 1](#item1))를 이용하면 불필요한 객체 생성을 피할 수 있다.
```java Boolean.valueOf(String) ```
-
변경 가능한 객체이지만 변경할 일이 없다면 재사용한다.
*AS-IS*
```java public class Person { private final Date birthDate;
public boolean isBabyBoomer() { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); Date boomStart = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); Date boomEnd = gmtCal.getTime(); return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0; } } ```
*TO-BE*
```java public class Person { private final Date birthDate;
private static final Date BOOM_START; private static final Date BOOM_END;
static { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); BOOM_START = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); BOOM_END = gmtCal.getTime(); }
public boolean isBabyBoomer() { return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0; } } ```
static initialzer을 하지않고 [lazy initialization](#item71) 기법을 사용할 수도 있다. 하지만, 추천하지 않는다. 구현이 복잡해질 뿐더러 *TO-BE*로 개선한 것 이상으로 성능을 높이기 어렵기 때문이다([규칙 55](#item55)).
-
어댑터 TO-DO
-
JDK 1.5 이후, 쓸데없는 객체 생성하는 방법 추가 - autoboxing
```java public static void main(String[] args) { Long sum = 0L; for (long i = 0; i < Integer.MAX_VALUE; i++) { sum += i; } } ```
`sum`이 `long`이 아닌 `Long`으로 선언되어 있기 때문에 더해질때마다 객체가 생성된다(2^31개 생성). 객체 표현형 대신 기본 자료형을 사용하고, 생각지도 못한 자동 객체화가 발생하지 않도록 유의하라.
-
직접 관리하는 객체 풀을 만들어 객체 생성을 피하는 기법은 객체 생성 비용이 극단적으로 높지 않다면 사용하지 않는 것이 좋다.
독자적으로 관리되는 객체풀을 만들면,
-
코드의 복잡성
-
메모리 요구량 증가
-
성능 떨어짐: 사용해야할 상황 - 데이터베이스
-
접속 비용이 큼
-
라이선스 정책에 따라 연결 수가 제한될 수 있음
-
규칙 39는 방어적 복사<sub>defensive copy</sub>에 관한 것.
```java // 방어적 복사 방법 public Period(Date start, Date end) { this.start = new Date(start.getTime()); this.end = new Date(end.getTime()); } ```
-
규칙 5: "재사용이 가능하다면 새로운 객체는 만들지 말라"
-
[규칙 39](#item39): "새로운 객체를 만들어야 한다면 기존 객체는 재사용하지 말라" 방어적 복사가 요구되는 상황에서 객체를 재사용하는 것은 (쓸데없이 같은 객체를 만드는) 비용보다 훨씬 높다는 것에 유의하자. 필요할 때 방어적 복사본을 만들지 못하면 버그나 보안 결함으로 이어진다. 쓸데 없는 객체들은 고작 코드 스타일과 성능에나 영향을 줄 뿐이다.