2013년 8월 28일 수요일

[oraclejava커뮤니티에서 강좌, 오라클자바교육,오라클교육,자바교육잘합니다]자바 static 초기화ㅣ

자바 java static 초기화를 이용하자~~~


오라클자바커뮤니티에서 설립한  개발자실무교육6년차 오엔제이프로그래밍 실무교육센터
(신입사원채용무료교육, 오라클, SQL, 튜닝, 자바, 스프링, Ajax, jQuery, 안드로이드, 아이폰, 닷넷, C#, ASP.Net)  
www.onjprogramming.co.kr


생성자와 static factory method(객체를 만들거나 만들어진 객체를 리턴하는 메소드)를 모두 제공하는 불변 클래스가 있을 때 static factory method를  사용하면 객체를 중복 생성하는 것을 막을 수가 있습니다. 예를 들면 Boolean.valueOf(String)을 쓰는 것이 Boolean(String) 생성자를 사용하는 것보다 훨씬 좋습니다. 왜냐면? 생성자는 매 호출마다 새로운 객체를 생성 하지만 static factory method는 새로운 객체를 생성하지 않아도 됩니다. 즉 기존에 만들어진 객체를 return해 주면 됩니다.

불변하는 객체만 재 사용할 수 있는 것은 아닙니다. 가변객체이지만 내용이 변경되지 않는 경우라면 재사용 하는 것이 바람직 합니다.

아래의 경우를 보세요~

public class Person {
        private final Date birthDate;

        public Person(Date birthDate) {
                this.birthDate = birthDate;
        }

        public boolean isBabyBoomer() {
                Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

                gmtCal.set(1950, Calendar.JANUARY, 1, 0, 0, 0);
                Date boomStart = gmtCal.getTime();

                gmtCal.set(1980, Calendar.JANUARY, 1, 0, 0, 0);
                Date boomEnd = gmtCal.getTime();

                return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;       
        }

}

위 클래스의 isBabyBoomer() 메소드는 호출될 때 마다 Calendar의 인스턴스 한 개, TimeZone인스턴스 한 개, Date 인스턴스 두개를 만들게 됩니다. 이 인스턴스들은 메소드를 아무리 호출 하더라도 변하지 않는 것이므로 static을 이용하여 아래와 같이 구현하는 것이 바람직 합니다.

public class Person {
        private final Date birthDate;

        public Person(Date birthDate) {
                this.birthDate = birthDate;
        }

        private static final Date BOOM_START;
        private static final Date BOOM_END;

        static {
                Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

                gmtCal.set(1950, Calendar.JANUARY, 1, 0, 0, 0);                
                BOOM_START = = gmtCal.getTime();

                gmtCal.set(1980, Calendar.JANUARY, 1, 0, 0, 0);
                BOOM_END = gmtCal.getTime();
        }


        public boolean isBabyBoomer() {       
                return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;       
        }

}


수정된 코드에서는 Calendar, Date, TimeZone을 정적 초기화 할 때 한번만 호출되므로 성능에 있어서도 상당히 좋아짐을 확인 할 수 있습니다. isBabyBoomer 메소드를 100번 정도 호출 시 수행 시간은 100배 정도 차이가 날 수 있습니다. 물론 코드의 가독성 역시 좋아 졌음을 눈으로 확인 할 수 있습니다.

위 코드에서 isBabyBoomer 메소드가 전혀 호출 되지 않는 경우(거의 없는 경우지만)에도 static 초기화는 수행이 되므로 단점이 될 수 있습니다.

댓글 없음:

댓글 쓰기