iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0
Software Development

深入淺出Java 30天系列 第 19

Day 19: 最小化可變性(下)

  • 分享至 

  • xImage
  •  

昨天說了如何設計immutable類別,以及物件狀態改變時該怎麼辦,今天會提出另外兩個方法,並說明immutable類別有什麼缺點,有什麼解法。

除了像昨天介紹的方法一樣,透過constructor或方法取得新的物件,也可以預先宣告一些特定用途的物件,並且設為final不只可以讓物件變immutable,也可以讓其他使用者重複使用

private final int x;
    private final int y;

    public static final Point ORIGIN = new Point(0, 0);
    public static final Point ONE_TO_ONE = new Point(1, 1);

    // Constructor
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Point{" + "x=" + x + ", y=" + y + '}';
    }

    public static void main(String[] args) {
        System.out.println("Original Point: " + Point.ORIGIN); 
    }
}

但如果有一些欄位在實體化之後沒有立即使用的需要,也許可以不用先設為final ,需要使用的時候在計算並賦予欄位值,可以讓效能更佳。舉例來說,並不是每次實體化後都會用到hash code,或許一開始把儲存hash code的欄位設為null,後面需要在計算即可,就像Effective java的Item 71 lazy initialization介紹的方法一樣。

除了上面說的那兩個方法,還可以使用Item 1介紹過的static factories method,這個方法除了可以確保類別不能被繼承,被修改成mutable類別,而且還可以cache住物件,重複使用物件提升效能。

public final class Point {
    private final int x;
    private final int y;

    // 防止透過constructor產生物件
    private Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // 靜態工廠方法,用於創建 Point
    public static Point of(int x, int y) {
        return new Point(x, y);
    }

    @Override public String toString() {
        return "Point{" + "x=" + x + ", y=" + y + '}';
    }

    public static void main(String[] args) {
        // 使用靜態工廠方法創建新的 Point
        Point p1 = Point.of(0, 0);
        System.out.println("Point: " + p1);
    }
}

最後來說說immutable類別的缺點。由於每次有不同需求時,都要生成一個新的物件,這會影響系統的效能,舉例來說,BigInteger是一個immutable類別,如果對最低位數進行修改,需要生成一個新的物件,並且把其他位數都複製一次,這個過程會花費很多時間。 為了解決上述問題,可以參考下面的兩種解法:

  • 運算過程盡量拆解步驟,避免多次用過大數字進行運算,盡量使用primitive型別進行運算。
  • 另外提供mutable類別做這類處理。

上一篇
Day 18: 最小化可變性(上)
下一篇
Day 20: 最好使用composition而不是繼承(上)
系列文
深入淺出Java 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言