Item 05 : 불필요한 객체는 만들지 말라
(Avoid creating unnecessary objects)
불필요한 객체 만들지 않는법
- String
- static factory method
- static initializer
- Wrapper class
1. String
String s1 = new String("ABC"); String s2 = new String("ABC"); System.out.println(s2 == s1); //false(참조값 다름)
s1, s2에서 각각 객체생성을 했으므로 힙영역에 객체 2개가 생성이 된다.
String.class
는 불변 클래스(immutable class)라서
같은 문자열을 다른 객체로 만들 이유가 없다.
객체 하나를 생성하고 같은 참조값을 가지면 된다.
(어짜피 문자열이 바뀌면 새로 객체를 생성하니까)
String s1 = "ABC"; String s2 = "ABC"; System.out.println(s2 == s1); //true(참조값 같음)
s1
에서 String Constant pool
에 문자열 "ABC"가 할당되고,
s2
는 s1
과 같은 참조값을 가진다.
2. static factory method
System.out.println(new Boolean("true")); //새로운 객체 생성 System.out.println(Boolean.valueOf("true")); // static 자원 사용
Item01 에서의 static factory method의 2번째 장점과 같다.
3. static initializer
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 = gmsCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); Date boomEnd = gmtCal.getTime(); return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0; } }
위에서 isBabyBoomer()
함수 호출시 마다
Calendar
형 객체, TimeZone
형 객체, Date
형 객체 2개 를 만들어낸다.
모두 같은 값을 가지는데 함수 호출시마다 객체를 만들 이유가 없다.
Public class Person { private final Date birthDate; // 다른 필드와 메서드, 생성자는 생략 /** 베이비 붐 시대의 시작과 끝 **/ 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 birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0; } }
static
을 이용하여 클래스 초기화시 객체를 한번씩만 만들게 되었다.
BOOM_START
, BOOM_END
가 상수라는 것도 직관적으로 알 수 있다.
isBabyBommer()
가 자주 실행될 수록 성능은 더 좋아질 것이다.
반면, 한번도 실행되지 않는다면 쓰데없는 초기화였다.
4. 기본 자료형
Public static void main(String[] args) { Long sum = 0L; for ( long i = 0; i < Integer.MAX_VALUE; I++) { sum = sum + i ; } System.out.println(sum); }
변수sum
이 Long
형으로 선언되었다.
for문을 돌 때마다 새로운 Long
형 객체를 생성할 것이다.
아래 코드는 Long
형에서 -> long
형으로만 바꼈다.
Public static void main(String[] args) { //위 코드에서 //Long -> long 만 바꿈. long sum = 0L; for ( long i = 0; i < Integer.MAX_VALUE; I++) { sum = sum + i ; } System.out.println(sum); }
sum이 참조변수가 아니라 기본자료형이기 때문에 객체생성이 이루어지지 않는다.
객체표현형 대신 기본자료형을 사용하고,
생각지도 못한 자동 객체화(Auto Boxing)가 발생하지 않도록 유의하자.
공감과 댓글은 제게 큰 힘이 됩니다 !
'Old Posts > Effecttive Java' 카테고리의 다른 글
Item08. equals를 재정의할 때는 일반 규약을 따르라 (0) | 2018.02.28 |
---|---|
Item06. 유효기간이 지난 객체 참조는 폐기하라 (0) | 2018.02.25 |
Item04. 객체 생성을 막을 때는 private 생성자를 사용하라 <이펙티브자바> (0) | 2018.02.23 |
Item03. 싱글톤을 쓸 때 property는 private 생성자나 enum타입으로 하라 <이펙티브자바> (0) | 2018.02.22 |
Item02. 생성자 인자가 많을 때는 Builder패턴 적용을 고려하라 <이펙티브자바> (0) | 2018.02.22 |