首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Effective Java 條目 3:避免創建不必要的對象,善用靜態工廠與單例模式

     編輯:Java 綜合教學

避免重複創建昂貴對象的實戰優化

《Effective Java》條目 3 指出:若對象不可變且頻繁使用,應避免重複創建,改用靜態工廠方法或單例模式復用實例。

反例:每次調用都創建 Calendar 對象

public class PersonSlow {
    private final Date birthDate;
    public PersonSlow(Date birthDate) { this.birthDate = new Date(birthDate.getTime()); }

    public boolean isBetweenTheDate() {
        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
        Date timeStart = gmtCal.getTime();
        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
        Date timeEnd = gmtCal.getTime();
        return birthDate.compareTo(timeStart) >= 0 && birthDate.compareTo(timeEnd) < 0;
    }
}

每次調用 isBetweenTheDate() 都創建兩個 Calendar 實例,性能開銷大。

正例:靜態代碼塊預先初始化

public class PersonFast {
    private Date birthDate;
    private static final Date BOOM_START;
    private static final Date BOOM_END;

    public PersonFast(Date birthDate) { this.birthDate = new Date(birthDate.getTime()); }

    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 isBetweenDate() {
        return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;
    }
}

靜態塊隨類加載執行一次,BOOM_START/END 成為常量,後續調用零創建開銷。若方法被千萬次調用,性能提升顯著。

擴展建議

  • 優先使用基本類型而非包裝類型(避免自動裝箱創建對象)。
  • 對於可變對象,考慮對象池或線程局部變量復用。
  • 工具類構造器私有化,提供靜態工廠方法返回單例或緩存實例。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved