> For the complete documentation index, see [llms.txt](https://yihyuns-gitbook.gitbook.io/today-i-learned/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yihyuns-gitbook.gitbook.io/today-i-learned/java/effective-java/item_6._reuse_instance.md).

# Item 6. 불필요한 객체 생성을 피하라

## 불필요한 객체 생성의 예시

### 생성자를 통한 String의 할당

* String은 보통 인스턴스를 생성할 때 “문자열” 형태로 초기화함
* 이는 `String constant pool`을 통해 정확히 동일한 문자열은 재사용하기 위함
* 그러나 new String(”문자열”)을 통해 할당하면 단순히 “문자열”을 통해 할당한 것과 정확히 동일한 동작을 함에도, 새 객체를 생성하게 됨

### 생성자를 통한 Wrapper의 할당

* wrapper 또한 `valueOf` 메소드를 통해 할당할 것을 권장하는데, 이는 생성자를 통해 생성하면 무조건 새 객체가 생성되지만 valueOf를 통해 생성하면 캐싱을 이용해 특정 범위 내 객체는 재사용이 가능하기 때문
  * Java 9부터는 Wrapper 클래스의 생성자가 deprecated 되었음
* 이는 `Item 1`과 연관지어, 정적 팩토리 메서드를 사용하는 경우 생성자와 달리 반드시 새 객체를 반환할 필요가 없는 것의 이점을 보여주고 있음

### Wrapper의 무분별한 사용에 의한 빈번한 오토 박싱

```java
public long sum(long max) {
		Long sum = 0L;
		for (long i = 0; i <= max; i++) {
			sum += i;
		}
}
```

* 위의 코드는, 단순히 sum을 long이 아닌 Long으로 선언했기 때문에 심각한 비효율을 초래
* sum += i 연산이 이루어질 때마다 새로운 Long 인스턴스가 생성됨

## 언제 객체를 재사용?

* 불변임이 확실할 때 캐싱을 통해 반복해서 재사용
* 생성 비용이 비싼 객체는 Pool을 통해 사용 후 회수하는 방식으로 재사용
  * Connection Pool, Thread Pool과 같은 것이 이에 해당
  * 하지만 Pool 방식은 코드 복잡도를 증가시키고, 메모리 사용량을 늘리기 때문에(미리 여러 객체를 선언해 가지고 있는 것이므로), 비용이 비싼 객체에만 적용해야 함
  * 최근 JVM의 GC는 가벼운 객체를 다루는 것에 큰 부담을 느끼지 않음

## 재사용을 조심할 것

* 재사용할 수 있는 것을 재사용하지 않았을 때에 발생하는 것은 `성능 이슈`
* 재사용할 수 없는 것을 재사용했을 때에는 `버그`와 `보안 취약점`이 발생 가능
* 따라서 객체를 재사용하고자 할 때에는 정말로 재사용이 가능한 경우에 해당하는지 신중하게 결정해야 함
