Effective Java Item25:將原始碼檔案限制為單一top-level的類別

整理 Effective Java 書中 Item 25:Limit source files to a single top-level class 心得筆記

主旨:保持一檔一類別,避免隱藏的地雷

Java 技術上允許你在一個 .java 檔案中定義多個 top-level 類別(也就是非巢狀的 public 或 package-private 類別),但這麼做其實是一個踩雷設計。這會讓你的程式行為變得難以預測,尤其當你在不同檔案中定義了相同名稱的類別,編譯結果會依照檔案的編譯順序而不同,產生極大的風險。

Read more

Effective Java Item24:比起非靜態成員類型,更偏好靜態成員類型

整理 Effective Java 書中 Item 24: Prefer static member classes to non-static member classes 心得筆記

主旨

在 Java 中,巢狀類別(Nested Class)是一種將類別定義在另一個類別內部的設計方式。根據是否需要外部類別的實例,有四種巢狀類別:static member classnon-static member classlocal classanonymous class。本篇聚焦在:當巢狀類別不需要外部類別實例時,應優先使用 static member class,這樣可以節省記憶體、提升效能、避免記憶體洩漏,也對設計更有彈性。

Read more

Effective Java Item23:偏好使用類別階層而非標籤類別

整理 Effective Java 書中 Item 23: Prefer class hierarchies to tagged classes 心得筆記

主旨

在寫Java時,有時我們會想設計一個類別,可以代表「好幾種不同型態的物件」。這時,有些人會選擇用一個「tag 欄位」來做判斷,稱為 tagged class。但這樣的寫法其實有很多問題,本條目會說明為什麼應該用「類別階層」來取代「tagged class」。

🧨 什麼是 Tagged Class?

來看一個實際範例:

// 不推薦的 tagged class 寫法
class Notification {
    enum Type { EMAIL, SMS }

    final Type type;
    String emailAddress;
    String phoneNumber;
    String message;

    Notification(String emailAddress, String message) {
        this.type = Type.EMAIL;
        this.emailAddress = emailAddress;
        this.message = message;
    }

    Notification(String phoneNumber, String message, boolean isSMS) {
        this.type = Type.SMS;
        this.phoneNumber = phoneNumber;
        this.message = message;
    }

    void send() {
        switch (type) {
            case EMAIL:
                System.out.println("Sending EMAIL to " + emailAddress + ": " + message);
                break;
            case SMS:
                System.out.println("Sending SMS to " + phoneNumber + ": " + message);
                break;
        }
    }
}
Read more

Effective Java Item22:介面只能拿來定義型別,不要拿來存常數

整理 Effective Java 書中 Item 22: Prefer interfaces to abstract classes 心得筆記

主旨

Java 的介面(interface)本質是用來定義「型別」的 —— 換句話說,介面要描述的是「這個物件可以做什麼」。如果你只是想要存一些常數,卻用介面來達成,那麼你就誤用了這個語言工具。

Read more

Effective Java Item21:設計介面要有前瞻性

整理 Effective Java 書中 Item 21: Design interfaces for multiple inheritance 心得筆記

主旨

Java 8 引入了 default method,終於讓介面可以新增方法而不會立刻讓現有的實作壞掉。但這個看似萬能的解法,其實潛藏不少風險,特別是對原本沒設計來支援這些方法的舊實作。這篇提醒你:設計介面時最好一開始就想清楚,因為事後「加東西」很可能會讓系統爆炸。

點出問題:default method 的魔法有限

在 Java 8 之前,介面一旦公開出去,就幾乎不能再改。加一個新方法,所有實作都會爆錯。default method 的出現,讓我們「表面上」可以擴充介面,不用動到原本的實作。

Read more