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

Java 不可變類實例緩存模式:以 Integer.valueOf 為例

     編輯:Java 相關知識

不可變類與實例復用的價值

不可變類的實例狀態創建後永不改變,天然適合多線程共享與跨組件傳遞。為減少內存佔用與 GC 壓力,應盡可能復用相同屬性值的實例。JDK 1.5 在 Integer 中引入實例緩存,正是這一模式的經典應用。

Integer.valueOf 的緩存邏輯

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

默認緩存範圍 [-128, 127],可通過 -XX:AutoBoxCacheMax 擴大上限。對比 new Integer(10) 每次創建新對象,valueOf(10) 在緩存命中時返回同一引用,故 Integer.valueOf(10) == Integer.valueOf(10) 為 true,而 new Integer(10) == new Integer(10) 為 false。

自定義不可變類實現緩存:Name 類示例

使用 SoftReference 防止緩存佔用過多堆內存,JVM 在內存不足時可回收:

import java.util.*;
import java.lang.ref.SoftReference;

public final class Name {
    private final String firstName;
    private final String lastName;

    // 緩存:鍵為 "firstName#lastName",值為 SoftReference
    private static final Map> CACHE = new HashMap<>();

    private Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public static Name valueOf(String firstName, String lastName) {
        String key = firstName + "#" + lastName;
        SoftReference ref = CACHE.get(key);
        if (ref != null) {
            Name cached = ref.get();
            if (cached != null) return cached; // 緩存命中且未被回收
        }
        // 未命中或已被回收,創建新實例並放入緩存
        Name created = new Name(firstName, lastName);
        CACHE.put(key, new SoftReference<>(created));
        return created;
    }

    // getter、equals/hashCode、toString 省略
}

決策指南:何時使用緩存?

並非所有不可變類都適合緩存,需同時滿足:

  1. 實例總量有限:如枚舉值、常用數值範圍、固定配置項
  2. 高頻訪問且長壽命:程序運行期間反復使用,生命周期接近應用壽命

若實例種類無上限(如用戶輸入的任意字符串)或使用頻率低,緩存反而增加內存負擔與管理複雜度。

設計提示

  • 同時提供 public 構造器與靜態工廠方法,讓調用方按需選擇
  • 緩存鍵設計需確保唯一性,複雜屬性可用 JSON 序列化或自定義 Key 類
  • 考慮線程安全:ConcurrentHashMap + computeIfAbsent 或雙重檢查鎖
  • 提供緩存統計/清理接口,便於監控與測試
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved