Book Summary&Review/이펙티브 자바 (Effective Java 3E)

Item6. 불필요한 객체 생성을 피하라

찹키리 2026. 1. 28. 10:02

👎 불필요한 객체 생성

  • 기존 객체를 재사용해야 한다면 새로운 객체를 만들지 마라

 

[EX. 불필요한 객체 생성의 예]

String s = new String("bikini");

// 개선 예
String s = "bikini";

 

[EX. 불필요한 객체 생성의 예2 - 오토박싱]

private static long sum() {
	Long sum = 0L;
	for(long i = 0; i <= Integer.MAX_VALUE; i++)
		sum += i; // 불필요한 Long 인스턴스가 계속 만들어지고 있음,,
		
	return sum;
}

 

 

👍 객체의 재사용

대안1. 정적 팩터리 메서드

  • 생성자는 호출할 때마다 새로운 객체를 만들지만, 팩터리 메서드는 그렇지 않음
  • 불변 객체 뿐 아니라 가변 객체 중에서도 사용 중 변경되지 않을 것임을 안다면 재사용 가능

 

[EX. 불변 클래스에서 생성자 대신 제공하는 정적 팩터리 매서드]

Boolean.valueOf(String)

// Java 9에서는 이 생성자가 deprecated API로 지정되었다.
Boolean(String)

 

대안2. 캐싱

  • 생성 비용이 비싼 객체의 경우 캐싱하여 재사용하는 방법 권장

 

[EX.생성 비용이 비싼 Pattern 인스턴스를 사용해 로마 숫자를 확인하는 소스코드]

static boolean isRomanNumeral(String s) {
	return s.matches("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}

 

[EX.Pattern 인스턴스(불변)를 클래스 초기화(정적 초기화) 과정에서 직접 생성해 캐싱, 재사용]

public class RomanNumerals {
	private static final Pattern ROMAN = Pattern.compile(
		"^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$"
	);
	
	static boolean isRomanNumeral(String s) {
		return ROMAN.matcher(s).matches();
	}
}

 

 

👆 유한 상태 머신 (finite state machine)

  • 가질 수 있는 상태가 한정되며, 한 번에 한 가지 상태만 유지

 

👆 객체 풀 패턴 (Object Pool Pattern)

  • 메모리 할당 및 해제에 드는 오버헤드를 줄이고 성능 향상을 위해 자주 사용되는 객체를 미리 생성하여 보관, 필요할 때 재사용하는 기법