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

《Effective Java》學習筆記:C 語言結構在 Java 中的四種替代模式

     編輯:Java 相關知識

從 C 結構到 Java 物件導向的思維轉換

《Effective Java》第 19-22 條針對 C 語言結構、聯合、枚舉、函數指針在 Java 中的替代方案。Java 無結構體、聯合、枚舉(JDK 5.0 前)、函數指針,但通過類、接口、枚舉類型(5.0+)提供更安全、更具表達力的替代。本文梳理四大替代模式與核心原則。

第 19 條:用類替代結構體 —— 封裝與不變性

C 結構體公開所有字段,Java 用 private 字段 + 公開訪問器/修改器實現封裝:


// C 結構體
struct Point { float x; float y; };

// Java 替代:不可變類模式(推薦)
public final class Point {
    private final float x;
    private final float y;
    public Point(float x, float y) { this.x = x; this.y = y; }
    public float getX() { return x; }
    public float getY() { return y; }
    // 可選:withX/withY 返回新實例,保持不可變性
}

優勢:類型安全、不可變性、防禦性拷貝、可添加驗證邏輯、支持 equals/hashCode/toString 契約。若必須可變,提供 setter 但需謹慎權衡線程安全。

第 20 條:用類層次替代聯合 —— 代數數據類型編碼

C 聯合同一內存區域存儲不同類型數據,Java 用密封類層次(sealed classes / 訪問者模式)實現:


// C 聯合
union Shape { Circle c; Rectangle r; Square s; };

// Java 替代:抽象基類 + 具體子類
abstract class Shape { abstract double area(); }
final class Circle extends Shape { ... }
final class Rectangle extends Shape { ... }
final class Square extends Shape { ... }
// JDK 17+ 可用 sealed class Shape permits Circle, Rectangle, Square

編譯器強制窮盡匹配(switch/visitor),消除「忘記處理某類型」的運行時風險。

第 21 條:用類替代枚舉結構 —— 類型安全枚舉模式

JDK 5.0 前無 enum 關鍵字,用「類型安全枚舉模式」模擬:


// C 枚舉
typedef enum { CIRCLE, RECTANGLE, SQUARE } Shape;

// Java 5.0 前模式
public class Shape {
    private final String name;
    private Shape(String name) { this.name = name; }
    public String toString() { return name; }
    public static final Shape CIRCLE = new Shape("CIRCLE");
    public static final Shape RECTANGLE = new Shape("RECTANGLE");
    public static final Shape SQUARE = new Shape("SQUARE");
}

// JDK 5.0+ 原生枚舉(強烈推薦)
public enum Shape { CIRCLE, RECTANGLE, SQUARE }
// 可攜帶字段/方法/實現接口,天然單例、可序列化、可 switch

原生枚舉編譯器生成 values()/valueOf(),支持 EnumSet/EnumMap 高效位運算,完美替代 int 常量模式。

第 22 條:用類和接口替代函數指針 —— 策略模式本質

C 函數指針傳遞行為,Java 用函數式接口(單抽象方法接口)+ Lambda(JDK 8+)實現:


// C 函數指針
int (*cmp)(void*, void*);

// Java 7 匿名內部類
Arrays.sort(arr, new Comparator() {
    public int compare(Object a, Object b) { ... }
});

// Java 8+ Lambda
Arrays.sort(arr, (a, b) -> ...);
// 或方法引用
Arrays.sort(arr, String::compareToIgnoreCase);

Comparator、Runnable、Callable、Function 等標準函數式接口構成行為參數化的基礎設施。

核心原則總結

C 構造Java 替代關鍵優勢
structfinal class + private final fields封裝、不可變、類型安全
unionsealed class hierarchy / visitor窮盡匹配、編譯期檢查
enumenum (JDK 5+) / typesafe enum class單例、可序列化、豐富行為
function pointerfunctional interface + lambda類型推導、閉包、方法引用

Java 通過「類即模塊、接口即契約、枚舉即類、函數即對象」的設計哲學,將 C 的弱類型、手動內存、無名空間機制轉化為強類型、自動管理、豐富生態的現代語言特性。

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