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

Java 不可變對象深度解析:BigInteger 為例揭示「狀態不可變」設計精髓

     編輯:Java 程式設計入門

你是否遇到過這種情況:明明調用了 add() 方法,結果卻沒變?這不是 Bug,而是 不可變對象 的核心特性。本文以 BigInteger 為切入點,徹底講透不可變模式的原理、優勢與正確使用姿勢。

經典誤區:以為修改了,實則無效

BigInteger total = BigInteger.ZERO;
total.add(new BigInteger("5000"));
total.add(new BigInteger("50000"));
total.add(new BigInteger("500000"));
System.out.println(total); // 輸出 0,而非預期的 555000

原因:BigInteger 實例一旦創建,內部數值 永不改變。所有運算方法(add、multiply 等)均返回 新實例,原對象保持不變。

正確用法:鏈式賦值或鏈式調用

// 方式一:逐步賦值
total = total.add(new BigInteger("5000"));
total = total.add(new BigInteger("50000"));
total = total.add(new BigInteger("500000"));

// 方式二:鏈式調用(推薦)
BigInteger total = BigInteger.ZERO
    .add(new BigInteger("5000"))
    .add(new BigInteger("50000"))
    .add(new BigInteger("500000"));
System.out.println(total); // 555000

Java 中常見的不可變類型

  • String:字符串拼接產生新對象
  • 包裝類:Integer、Long、Double 等
  • 大數類:BigInteger、BigDecimal
  • 時間類:LocalDate、Instant 等(Java 8+)

不可變模式的五大核心優勢

  1. 線程安全:無狀態變更,天然免疫競態條件,無需同步。
  2. 簡化設計:類不變式在構造時建立,生命周期內永遠成立。
  3. 安全共享:可自由緩存、作為 Map Key、Set 元素,無需防禦性拷貝。
  4. 構建高效:編譯器可優化(如字符串常量池、Integer 緩存)。
  5. 失敗原子性:方法拋異常時,對象狀態不會被破壞。

自定義不可變類實戰範本

public final class ImmutablePoint {          // 1. final 類,防繼承破壞
    private final int x;                     // 2. 所有字段 final + private
    private final int y;

    public ImmutablePoint(int x, int y) {    // 3. 構造器初始化所有字段
        this.x = x;
        this.y = y;
    }

    // 4. 僅提供 getter,無 setter
    public int getX() { return x; }
    public int getY() { return y; }

    // 5. 「修改」操作返回新實例
    public ImmutablePoint translate(int dx, int dy) {
        return new ImmutablePoint(x + dx, y + dy);
    }

    // 6. 防禦性拷貝(若持有可變組件)
    // private final Date date;
    // public Date getDate() { return new Date(date.getTime()); }
}

避坑指南

  • ❌ String s = "a"; s += "b"; 循環中拼接 → ✅ 用 StringBuilder
  • ❌ BigDecimal price = new BigDecimal(0.1); 浮點精度陷阱 → ✅ 用 new BigDecimal("0.1")
  • ❌ 將可變對象(List、Date)直接暴露給外部 → ✅ 返回防禦性拷貝或不可變視圖

總結

不可變對象不是「不能用」,而是「要用對方式」——把操作結果賦值回引用。這種設計哲學貫穿 Java 核心庫與現代框架,掌握它能寫出更健壯、並發友好的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved