5、避免建立不必要的物件

guanhang89發表於2016-06-08

避免建立不必要的物件

一般來說最好是重用物件,而不是每次需要的時候都建立一個相同的物件。

反例

千萬不要這樣做,因為穿進去的引數“aa”本身就是一個String例項

String s = new String("aa");

應該這樣:

String s = "aa";

而且,它可以保證對於所有同一臺虛擬機器中的執行的程式碼,只要它們包含相同的字串字面常量,該物件就會被重用

對於提供靜態工廠和建構函式的 不可變類,優先使用靜態工廠(不需要每次都建立新的)

除了重用不可變的物件外,還可以重用已知不會被修改的可變物件

反例:

//判斷一個人出生的時間是否在嬰兒潮期間內
public class Person {
    private final Date birthDate;

    public Person(Date birthDate) {
        // Defensive copy - see Item 39
        this.birthDate = new Date(birthDate.getTime());
    }

    // Other fields, methods omitted

    // DON'T DO THIS!
    //Date算出來實際就不需要改變了
    public boolean isBabyBoomer() {
        // Unnecessary allocation of expensive object
        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 birthDate.compareTo(boomStart) >= 0
                && birthDate.compareTo(boomEnd) < 0;
    }
}

正確案例:

class Person {
    private final Date birthDate;

    public Person(Date birthDate) {
        // Defensive copy - see Item 39
        this.birthDate = new Date(birthDate.getTime());
    }

    // Other fields, methods

    /**
     * The starting and ending dates of the baby boom.
     */
    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;
    }
}

通過維護自己的物件池(pool)來避免建立物件並不是一種好的做法,除非是重量級的物件,比如資料庫物件(代價昂貴)

相關文章