一葉笑天
          雄關漫道真如鐵, 而今邁步從頭越。 從頭越, 蒼山如海, 殘陽如血。
          posts - 73,comments - 7,trackbacks - 0
          如果一個對象是immutable的話,它總是可以被重用的。例如:
          String s = new String("stringette"); // DON'T DO THIS!
          這條語句每次執行時都會創建新的String。增強的版本是:
          String s = "stringette";
          這種形式使用單一的String實例,而不是每次都會創建新的String。
          使用static factory method可以避免創建不需要的對象。例如Boolean.valueOf(String)比Boolean(String)更具有優勢。構造函數每次都會創建新實例。而靜態工廠方不需要這樣做。
          舉一個簡單的例子:
          這個類包含有Date對象,這個值一旦被計算出來就從不改變。這個類構造一個person,有一個isBabyBoomer方法,來判斷這個person是否是“baby
          boomer,”  是否出生在1946年到1964年。
           1public class Person {
           2    private final Date birthDate;
           3
           4    // Other fields, methods, and constructor omitted
           5    // DON'T DO THIS!
           6    public boolean isBabyBoomer() {
           7        // Unnecessary allocation of expensive object
           8        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
           9        gmtCal.set(1946, Calendar.JANUARY, 1000);
          10        Date boomStart = gmtCal.getTime();
          11        gmtCal.set(1965, Calendar.JANUARY, 1000);
          12        Date boomEnd = gmtCal.getTime();
          13        return birthDate.compareTo(boomStart) >= 0
          14                && birthDate.compareTo(boomEnd) < 0;
          15    }

          16}
          isBabyBoomer方法不需要每次創建一個Calendar,TimeZone和兩個Date實例。為了避免不必要的創建,可以使用static初始化:
           1class Person {
           2    private final Date birthDate;
           3    // Other fields, methods, and constructor omitted
           4    /**
           5     * The starting and ending dates of the baby boom.
           6     */

           7    private static final Date BOOM_START;
           8    private static final Date BOOM_END;
           9    static {
          10        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
          11        gmtCal.set(1946, Calendar.JANUARY, 1000);
          12        BOOM_START = gmtCal.getTime();
          13        gmtCal.set(1965, Calendar.JANUARY, 1000);
          14        BOOM_END = gmtCal.getTime();
          15    }

          16
          17    public boolean isBabyBoomer() {
          18        return birthDate.compareTo(BOOM_START) >= 0
          19                && birthDate.compareTo(BOOM_END) < 0;
          20    }

          21}
                增強的版本中只創建Calendar,TimeZone和兩個Date一次。當這個方法頻繁調用的時候性能會得到很大的提高。Calendar創建是開銷是很大的。
                如果isBabyBoomer從未調用,BOOM_START和BOOM_END 也是不需要初始化的??梢允褂胠azily initializing來加載它們。但是這不是推薦的。經常使用lazy initialization會使實現變得復雜,未必優于已經取得的性能。
              在上面的例子中,很顯然是由于對象在初始化后不再修改才重用。其他場合下未必這么顯然。例如adapter,也稱為views。adaper代表一個后臺對象,提供一個可供選擇的接口給后臺對象。由于adapter沒有狀態,因此不需要創建多個實例。
             例如Map接口的keySet方法返回一個Map對象的Set視圖,包含所有map中的key值。顯然在給定的Map上每個調用keySet都會創建一個Set實例,但是每個調用都會返回相同的Set實例。雖然返回的Set是可變的,但是所有的對象都是一致的,當其中一個變化了,所有的都要改變。這是因為在它們后面是相同的Map實例。創建多個keySet視圖對象無害但無意義。
            在1.5中autoboxing可以創建無用的對象。容許程序員混合基本類型和包裝類。自動boxing和unboxing操作??聪旅娴睦樱河嬎闼姓齣nt的和。必須使用long才能保存所有正int的和。
          1// Hideously slow program! Can you spot the object creation?
          2public static void main(String[] args) {
          3  Long sum = 0L;
          4  for (long i = 0; i < Integer.MAX_VALUE; i++{
          5    sum += i;
          6  }

          7  System.out.println(sum);
          8}
          隨著程序可以得到正確結果,但是計算會慢。主要由于一個字符的錯誤。變量sum被聲明為Long,而不是long,這意味著程序將要創建2(31)個無用的Long實例。這個教訓是:盡量使用基本類型boxed到基本類型,當心無意識的autoboxing。
             通過創建對象池來避免對象創建不是一個好主意,除非池中的數據極其重量級。例如數據庫連接。創建連接的花銷很高,最好重用這個對象。


          posted on 2008-06-19 21:47 一葉笑天 閱讀(213) 評論(0)  編輯  收藏 所屬分類: JAVA技術
          主站蜘蛛池模板: 灌阳县| 凤翔县| 腾冲县| 泊头市| 湟源县| 迁西县| 宁阳县| 射洪县| 建水县| 云林县| 乌拉特后旗| 若尔盖县| 客服| 紫阳县| 临夏市| 旺苍县| 宜章县| 建瓯市| 黄浦区| 调兵山市| 英吉沙县| 大邑县| 高密市| 会昌县| 格尔木市| 郯城县| 汤阴县| 四子王旗| 昆明市| 太仓市| 沾化县| 泸州市| 内丘县| 富阳市| 大方县| 美姑县| 普安县| 防城港市| 堆龙德庆县| 临西县| 曲阳县|