자바에서는 객체 생성 비용이 크고 GC 부담도 존재하므로,
필요한 경우에만 객체를 생성하고, 재사용 가능한 객체는 반드시 재사용해야 한다.
이 원칙은 성능, 메모리 효율성, 유지보수성에 직접적인 영향을 준다.
String s = new String("bikini");"bikini"는 이미 **상수 풀(Constant Pool)**에 존재하는 불변 객체.new String(...)은 매번 새로운 인스턴스를 생성 → 메모리 낭비 및 GC 부담 증가.==비교 시 참조값을 비교하기 때문에,"bikini"리터럴과는 다른 객체로 인식될 수 있음.
String s = "bikini";- 상수 풀에 존재하는 동일한
String인스턴스를 재사용. String은 불변(Immutable) 객체이므로 공유해도 안전함.- 객체 생성을 피하므로 성능과 메모리 사용 효율 향상.
자바는 기본형과 래퍼 클래스 간의 **자동 변환(박싱/언박싱)**을 지원한다.
그러나 반복문 등에서 무심코 사용하면 불필요한 객체가 대량 생성될 수 있다.
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}Long sum = 0L→long값이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은 기본형으로 스택에 값 저장, 박싱 없이 연산됨.- ➜ 객체 생성 없음, 성능과 메모리 사용 측면에서 훨씬 효율적.
자바는 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); // falseInteger.valueOf(127)→ 캐싱된 동일 객체 반환.Integer.valueOf(128)→ 새로운 객체 생성.- ➜ 래퍼 클래스는
.equals()로 비교하는 것이 안전하다.
| 항목 | 권장 여부 | 설명 |
|---|---|---|
new String("text") |
❌ | 불필요하게 매번 새로운 객체 생성 |
"text" 리터럴 |
✅ | 상수 풀 재사용 |
Long sum = 0L |
❌ | 오토박싱 → 반복마다 객체 생성 |
long sum = 0L |
✅ | 기본형 사용으로 성능 최적화 |
Integer.valueOf() |
✅ | -128 ~ 127 범위는 캐싱된 객체 재사용 |
"객체는 꼭 필요한 순간에만 생성하자.
재사용할 수 있는 객체는 새로 만들지 말자."
- 기본형을 우선 사용하고,
- 불변 객체는 공유하며,
- 반복문 안에서는 박싱을 피해야 한다.
- 이 원칙 하나로도 자바 프로그램의 효율성이 달라진다.