Skip to content

Latest commit

 

History

History
111 lines (78 loc) · 3.33 KB

File metadata and controls

111 lines (78 loc) · 3.33 KB

✅ Effective Java - Item 6: 불필요한 객체 생성을 피하라

📌 핵심 요약

자바에서는 객체 생성 비용이 크고 GC 부담도 존재하므로,
필요한 경우에만 객체를 생성하고, 재사용 가능한 객체는 반드시 재사용해야 한다.
이 원칙은 성능, 메모리 효율성, 유지보수성에 직접적인 영향을 준다.


❌ 하지 말아야 할 극단적인 예

String s = new String("bikini");
  • "bikini"는 이미 **상수 풀(Constant Pool)**에 존재하는 불변 객체.
  • new String(...)매번 새로운 인스턴스를 생성메모리 낭비 및 GC 부담 증가.
  • == 비교 시 참조값을 비교하기 때문에, "bikini" 리터럴과는 다른 객체로 인식될 수 있음.

✅ 올바른 방식

String s = "bikini";
  • 상수 풀에 존재하는 동일한 String 인스턴스를 재사용.
  • String불변(Immutable) 객체이므로 공유해도 안전함.
  • 객체 생성을 피하므로 성능과 메모리 사용 효율 향상.

⚠️ 오토박싱(AutoBoxing)의 함정

자바는 기본형과 래퍼 클래스 간의 **자동 변환(박싱/언박싱)**을 지원한다.
그러나 반복문 등에서 무심코 사용하면 불필요한 객체가 대량 생성될 수 있다.

❌ 잘못된 코드 예시

Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
    sum += i;
}
  • Long sum = 0Llong 값이 Long 객체로 오토박싱됨.
  • sum += i는 내부적으로 sum = Long.valueOf(sum.longValue() + i);
  • 루프마다 새로운 Long 객체가 힙에 생성됨성능 저하 및 GC 부담 증가.

✅ 개선된 코드 예시

long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
    sum += i;
}
  • long은 기본형으로 스택에 값 저장, 박싱 없이 연산됨.
  • 객체 생성 없음, 성능과 메모리 사용 측면에서 훨씬 효율적.

🧠 Wrapper 클래스의 캐싱

자바는 Integer, Long, Short, Byte, Character, Boolean 등에 대해
-128 ~ 127 범위의 값을 캐싱하여 같은 객체를 재사용한다.

Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true

Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false
  • Integer.valueOf(127)캐싱된 동일 객체 반환.
  • Integer.valueOf(128)새로운 객체 생성.
  • 래퍼 클래스는 .equals()로 비교하는 것이 안전하다.

✅ 요약

항목 권장 여부 설명
new String("text") 불필요하게 매번 새로운 객체 생성
"text" 리터럴 상수 풀 재사용
Long sum = 0L 오토박싱 → 반복마다 객체 생성
long sum = 0L 기본형 사용으로 성능 최적화
Integer.valueOf() -128 ~ 127 범위는 캐싱된 객체 재사용

📚 결론

"객체는 꼭 필요한 순간에만 생성하자.
재사용할 수 있는 객체는 새로 만들지 말자."

  • 기본형을 우선 사용하고,
  • 불변 객체는 공유하며,
  • 반복문 안에서는 박싱을 피해야 한다.
  • 이 원칙 하나로도 자바 프로그램의 효율성이 달라진다.