-
item 6 불필요한 객체 생성을 피하라책/이펙티브 자바 2022. 2. 16. 09:01
ITEM 6 불필요한 객체 생성을 피하라
같은 기능의 객체라면 매번 생성 하는것 보다는 객체를 재사용 하자
- 객체 재사용은 성능상 이점을 가져다준다
안좋은예시
String str = new String("hello");
위와 같은 코드는 실행시 매번 hello 라는 값을 가진 인스턴스를 새로 만들게 된다
- 인자로 들어가는 hello는 이미 만들려고 하는것 그 자체이다
- 전혀 쓸데 없는 행위이다
- 개수가 많아진다면 그만큼 쓸데없는 String 인스턴스가 생길것이다
좋은예시
String str = "hello";
위의 코드는 첫번째 예시와 같은 결과를 도출한다
- 위의 코드는 인스턴스를 한번만 생성하고 재사용 하기 때문에 불필요한 인스턴스에 생성을 방지한다
- 또한 위의 코드는 같은 가상머신 내에서 이러한 문자열 리터럴을 사용하는 코드는 전부 이 객체를 재사용한다
해결방안
- item1에서 나온 정적 팩터리 메서드를 사용한다면 불필요한 객체의 생성을 피할 수 있다
- 예) Boolean(String) 대신 Boolean.valueOf(String) 으로 사용
- 생성자를 사용한다면 호출시 새로운 객체가 생성되지만 정적 팩터리 메서드를 사용한다면 그렇지 않다
- 불변객체 뿐만이 아닌 가변 객체라 할지라도 사용중 객체가 변하지 않는것을 안다면 재사용이 가능하다
이런경우 재사용을 고려 해보자
- 같은 결과를 도출하는 인스턴스를 매번 재생성 하는 경우
- 생성 비용이 비싼 객체를 반복해서 사용하는 경우
- 이러한 경우에는 캐싱을 해서 사용하자
- 예) 만약 String.matches()를 사용한다면 구현부에 직접 넣지 않고 클래스 상단에 static으로 선언하여 클래스 생성시 정적 초기화 되도록 한다
- 메서드 구현부에 넣는다면 해당 메서드 종료 시점에 가비지 컬렉션 대상이 되기 때문에 비싼 객체를 일회용으로 쓰게 되므로 반복해서 사용한다면 비효율적이다
- 위의 방식도 static으로 선언한 필드가 사용되지 않는 경우 비효율적이라 볼수 있다
- 이러한 문제를 해결하기위한 지연 초기화라는 기법도 있지만 코드 복잡성이 증대되기 때문에 권장하지는 않는다
- 이러한 경우에는 캐싱을 해서 사용하자
- 불필요하게 오토박싱을 사용하는 경우
- 불필요한 오토 박싱이 일어나지 않도록 방식된 기본타입 보다는 기본 타입을 사용하는것이 안전하다
마무리
- 객체 생성이 비싸니까 피해야 된다는 말은 아니다
- 일반적으로 객체를 생성하는 행위는 명확성, 간결성, 기능에 도움이 된다
- 그저 재사용이 가능한 경우에는 고려해보자는 이야기이다
- 방어적 복사와 반대되는 개념이지만 코드 작성시 고려사항에서 방어적 복사가 더 우선순위가 높다
- 방어적 복사에 실패 한다면 직접적인 버그를 일으키지만 객체 생성은 성능과 가독성에만 영향을 주기 때문이다
'책 > 이펙티브 자바' 카테고리의 다른 글
item 8 finalizer와 cleaner사용을 피하라 (0) 2022.02.18 item 7 다 쓴 객체 참조를 해제하라 (0) 2022.02.17 item 5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) 2022.02.15 item 4 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) 2022.02.14 item 3 private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) 2022.02.11