티스토리 뷰
(Effective Java) 규칙6. 불필요한 객체 생성을 피하라
불필요한 객체..
-
기능적으로 동일한 객체는 필요할 때마다 만드는 것보다 재사용하는 편이 낫다.
- 객체를 재사용하는 프로그램은 더 빠르고 우아함
- 변경 불가능 (immutable) 객체는 언제나 재사용할 수 있음
-
절대적으로 피해야 할 극단적 예
String s = new String("Sample string");
- 위 문장은 실행될 때마다 String 객체를 만듬
- "Sample string"은 그 자체로 String 객체임
- 위 문장은 실행될 때마다 String 객체를 만듬
-
바람직한 예
String s = "Sample String";
- 위 문장은 실행될 때마다 객체를 만드는 대신, 동일한 String 객체를 사용함
- 같은 머신(VM)에서 실행되는 모든 코드가 해당 객체를 재사용하게 됨
- "Sample String" 이라는 String 객체를 여러 곳에서 참조하는 것임
- 위 문장은 실행될 때마다 객체를 만드는 대신, 동일한 String 객체를 사용함
-
생성자와 정적 팩터리 메서드를 함께 제공하는 변경 불가능 클래스의 경우, 생성자 대신 정적 팩토리 메서드를 이용하면 불필요한 객체 생성을 피할 수 있을 때가 많다.
- 예) Boolean(String) 보다 Boolean.valueOf(String) 쪽이 바람직
- 생성자는 호출시 마다 새 객체를 만들지만, 정적 팩터리 메서드는 그러지 않음
변경 가능한 객체의 재사용
-
변경 가능한 객체도 재사용할 수 있다. (변경할 일이 없다면 말이다..)
-
흔히 발생하는 사소한 문제
-
문제 예
public class Person { private final Date birthDate; //다른 필드와 메서드, 생성자는 생략 //이렇게 하면 안된다! public boolean isBabyBoomer() { //생성비용이 높은 객체를 쓸데없이 생성한다 Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); Date boomStart = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); Date boomEnd = gmtCal.getTime(); return birthData.compareTo(boomStart) >= 0 && birthData.compareTo(boomEnd) < 0; } }
- 위에 보인 isBabyBoomer 메서드는 호출될 때마다 Calendar 객체 하나, TimeZone 객체 하나, 그리고 Date 객체 두 개를 쓸데 없이 만들어 냄
-
개선된 예
public class Person { private final Date birthData; /** * 베이비 붐 시대의 시작과 끝 */ private static final Date BOOM_START; private static final Date BOOM_END; static { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); BOOM_START = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); BOOM_END = gmtCal.getTime(); } public boolean isBabyBoomer() { return birthData.compareTo(BOOM_START) >= 0 && birthData.compareTo(BOOM_END) < 0; } }
- 개선된 Persen 클래스는 Calendar, TimeZone 그리고 Date 객체를 클래스가 초기화 될 때 한번만 만듬
- boomStart/End를 지역변수에서 static final 필드로 바꾸자 이 두 날짜가 상수라는 사실이 분명하게 드러나 읽기 좋은 코드가 됨
-
-
재사용 가능한 여부가 분명하지 않은 경우 (여담)
- 예) Map 인터페이스의 keySet() 메서드는 Map 객체의 Set 뷰를 반환하는 데 여러번 호출 했을 때에도 동일한 Set 객체를 반환함
- 객체 하나가 변경되면 다른 객체도 변경이 된다는 뜻
- keySet으로 뷰 객체를 여러 개 만들어도 될 것 같지만 쓸데없긴 마찬가지
- 예) Map 인터페이스의 keySet() 메서드는 Map 객체의 Set 뷰를 반환하는 데 여러번 호출 했을 때에도 동일한 Set 객체를 반환함
AutoBoxing
-
JDK 1.5 부터 쓸데없이 객체를 만들 새로운 방법이 생겼다. (자동 객체화(autoboxing))
- 자바의 기본 자료형과 그 객체 표현형을 섞어 사용할 수 있도록 해줌 (자동으로 변환이 이루어짐)
- 의미적인(semantic) 차이는 미미하지만 성능 차이는 무시하기 어려움
-
성능 차이 예
//무시무시할 정도로 느린 프로그램. 어디서 객체가 생성되는지 알겠는가? public static void main(String args[]) { Long sum = 0L; for (long i = 0; i < Integer.MAX_VALUE; i++) { sum += 1; } System.out.println(sum); }
- Long과 long의 성능 차이는 7배 가량 난다고 한다.
- sum에 더해질 때 마다 Long 객체는 생성됨
- 여기서의 교훈은, 객체 표현형 대신 기본 자료형을 사용하고, 생각지도 못한 자동 객체화가 발생하지 않도록 유의하라는 것
- Long과 long의 성능 차이는 7배 가량 난다고 한다.
핵심은..
- 객체를 만드는 비용이 높으니 무조건 피하라는 것은 아니다.
- 생성자 안에서 하는 일이 작고 명확하면 객체 생성과 반환은 신속하게 이루어짐 (최신 JVM이면 더더욱)
- 객체를 만들어서 코드의 명확성과 단순성을 높이고 프로그램의 능력을 향상시킬 수 있다면, 일반적으로는 만드는 것이 좋음
- 객체 풀(object pool)을 만들어 객체 생성을 피하는 기법은 객체 생성 비용이 극단적으로 높지 않다면 사용하지 않는 것이 좋다.
- 데이터 베이스 연결 같은 비용이 높은 객체들을 당연히 재사용하는 것이 맞음
끝으로
이 글이 도움이 되었다면, Google 광고 한번씩 클릭 부탁 드립니다. 🙏🙏🙏
광고 클릭은 많은 힘이 됩니다!
반응형
'프로그래밍 > EffectiveJava' 카테고리의 다른 글
(이펙티브 자바) 규칙18. 상속보다는 컴포지션을 사용하라 (0) | 2020.02.13 |
---|---|
(이펙티브 자바) 규칙 1. 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2020.02.11 |
(이펙티브 자바) 규칙4. 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2020.02.06 |
(이펙티브 자바) 규칙3. private 생성자나 열거 타입으로 싱글턴임을 보증하라 (0) | 2020.02.06 |
(이펙티브 자바) 규칙53. null 대신 빈 배열이나 컬렉션을 사용하라 (0) | 2020.02.01 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 스프링부트
- 일본 자전거 여행
- 배낭여행
- intelij
- 자바
- 배낭 여행
- 자전거 여행
- 일본 배낭여행
- effective java
- 텐트
- 일본 여행
- 이펙티브자바
- JavaFX
- springboot
- JavaFX Table View
- java
- 이펙티브 자바
- JavaFX Window Close
- TableView
- 인텔리제이
- git
- 이펙티브
- 일본여행
- JavaFX 테이블뷰
- 자전거
- windows
- effectivejava
- JavaFX 종료
- Java UI
- 방통대 과제물
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함