이펙티브 자바 2장 Item6를 요약한 내용입니다.
요즘 JVM의 가비지컬렉터는 최적화가 잘 되어 있어 가벼운 객체를 다룰 때는 객체 풀을 만들어 객체를 재사용하는 것보다 새로 생성하는게 훨씬 빠르다.
따라서 일반적으로 프로그램의 명확성, 간결성, 기능을 위해 객체를 추가로 생성하는 일은 문제가 되지 않는다.
하지만 굳이 필요하지 않는 객체 생성은 피하는 것이 좋다.
또한 객체를 재사용했을 때 문제가 없고, 객체 생성 비용이 큰 경우에는 객체를 재사용하는 것이 좋다.
불필요한 객체 생성을 줄이기 위해서는 생성자 대신 정적 팩터리 메서드를 사용하는 것이 좋다.
생성자는 호출할 때마다 새로운 객체를 만들지만 팩터리 메서드는 재사용되는 객체를 반환하는 경우가 많기 때문이다.
오토박싱이란 기본타입과 그에 대응하는 박싱된 기본 타입을 섞어 쓸 때 자동으로 변환해주는 기술이다.
오토박싱을 할 때 새로운 인스턴스가 생성된다.
따라서 의도치 않은 오토박싱을 주의해야 한다.
아래 메서드에서 사용하는 String.matches는 정규표현식으로 문자열형태를 확인하는 가장 쉬운 방법이다.
하지만 String.matches 메서드 내부에서 생성하는 Pattern 인스턴스는 한번 쓰고 버려지는데, 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})$");
}
성능을 개선하기 위해 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.matchers(s).matches();
}
}
미리 캐싱해놓는 인스턴스는 사용하기전까지 불필요하기 때문에 지연 초기화를 할 수 있지만 성능은 크게 개선되지 않기 때문에 권하지는 않는다.
방어적 복사란 객체를 재사용했을 때의 문제를 피하기 위해 새로운 객체를 생성하는 것이다.
객체생성비용이 큰 객체를 재사용할 때 성능적 이점을 얻을 수 있지만 객체를 재사용하는 경우 수많은 버그와 보안문제의 원인이 될 수 있다.
따라서 객체를 재사용함으로써 얻을 수 있는 이점과 문제점을 잘 파악한 후 현명하게 선택해야 한다.
[이펙티브 자바] Item 8. finalizer와 cleaner 사용을 피하라 | 2장 (1) | 2023.04.12 |
---|---|
[이펙티브 자바] Item 7. 다 쓴 객체 참조를 해제하라 | 2장 (0) | 2023.04.05 |
[이펙티브 자바] Item 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 | 2장 (1) | 2023.04.05 |
[이펙티브 자바] Item 4. 인스턴스화를 막으려거든 private 생성자를 사용하라 | 2장 (0) | 2023.03.29 |
[이펙티브 자바] Item 3. private 생성자나 열거타입으로 싱글턴임을 보증하라 | 2장 (0) | 2023.03.29 |