最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java枚舉(Enum)從基礎(chǔ)到高級(jí)應(yīng)用詳解

 更新時(shí)間:2026年05月08日 08:43:44   作者:北風(fēng)toto  
文章詳細(xì)介紹了Java枚舉(enum)的概念、基礎(chǔ)語(yǔ)法、內(nèi)置方法及高級(jí)用法,強(qiáng)調(diào)了枚舉在提高代碼類型安全性、可讀性和維護(hù)性方面的優(yōu)勢(shì),文中還列舉了添加字段、方法和實(shí)現(xiàn)接口等高級(jí)用法,并提供了命名規(guī)范、不可變性、異常處理等最佳實(shí)踐建議,需要的朋友可以參考下

一、 引言:什么是枚舉?

在編程中,我們經(jīng)常會(huì)遇到需要表示一組固定、預(yù)定義值的情況。例如:

  • 一周的七天(Monday, Tuesday, …, Sunday)
  • 季節(jié)(Spring, Summer, Autumn, Winter)
  • 訂單狀態(tài)(PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED)
  • HTTP 請(qǐng)求方法(GET, POST, PUT, DELETE, …)
  • 顏色(RED, GREEN, BLUE)

在沒(méi)有 enum 之前,開(kāi)發(fā)者通常會(huì)使用 int 常量或 String 常量來(lái)表示這些值,例如:

// 使用 int 常量
public class Status {
    public static final int PENDING = 0;
    public static final int CONFIRMED = 1;
    public static final int SHIPPED = 2;
    // ...
}

// 使用 String 常量
public class RequestMethod {
    public static final String GET = "GET";
    public static final String POST = "POST";
    public static final String PUT = "PUT";
    // ...
}

這種方式存在明顯的缺點(diǎn):

  1. 類型不安全: 編譯器無(wú)法保證傳入的 intString 值一定是我們定義的常量之一。processOrder(999)sendRequest("INVALID_METHOD") 在語(yǔ)法上是合法的,但在邏輯上是錯(cuò)誤的。
  2. 可讀性差: if(status == 1)if(status == Status.CONFIRMED) 難以理解。
  3. 維護(hù)困難: 常量值容易被誤用或修改,且不易發(fā)現(xiàn)。
  4. 缺乏功能: 常量只是一個(gè)值,無(wú)法附加行為或?qū)傩浴?/li>

Java 5 引入了 enum 類型,就是為了優(yōu)雅地解決這些問(wèn)題。

二、 基礎(chǔ)語(yǔ)法

enum 是 Java 的一個(gè)關(guān)鍵字,用來(lái)聲明一個(gè)枚舉類。

基本定義:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
  • Day 是枚舉類的名稱。
  • SUNDAY, MONDAY, … SATURDAY 是這個(gè)枚舉類的實(shí)例(也叫枚舉常量),它們是 Day 類型的唯一對(duì)象。每個(gè)實(shí)例都是 public static final 的,意味著它們是全局唯一的單例。

使用枚舉:

public class EnumExample {
    public static void main(String[] args) {
        Day today = Day.MONDAY; // 聲明并賦值

        // 使用 switch 語(yǔ)句
        switch (today) {
            case MONDAY:
                System.out.println("It's Monday. Back to work!");
                break;
            case FRIDAY:
                System.out.println("It's Friday. Weekend is coming!");
                break;
            default:
                System.out.println("It's " + today.name() + ".");
                break;
        }

        // 比較枚舉實(shí)例(推薦使用 ==,因?yàn)樗鼈兪菃卫?
        if (today == Day.MONDAY) {
            System.out.println("Yes, it's Monday.");
        }

        // 使用 equals 方法(也可以,但 == 更高效)
        if (today.equals(Day.MONDAY)) {
            System.out.println("Yes, it's Monday (using equals).");
        }
    }
}

三、 枚舉類的本質(zhì)

在 JVM 內(nèi)部,enum 實(shí)際上被編譯成一個(gè)繼承自 java.lang.Enum 的類。所以,Day 枚舉大致等價(jià)于以下的普通類定義(簡(jiǎn)化示意):

// 編譯器生成的類似代碼
final class Day extends Enum<Day> { // 枚舉類隱式繼承 Enum
    private static final Day SUNDAY = new Day("SUNDAY", 0);
    private static final Day MONDAY = new Day("MONDAY", 1);
    // ... 其他實(shí)例

    private static final Day[] $VALUES = {SUNDAY, MONDAY, /* ... */ SATURDAY};

    public static Day[] values() { // 自動(dòng)生成 values() 方法
        return $VALUES.clone();
    }

    public static Day valueOf(String name) { // 自動(dòng)生成 valueOf() 方法
        return Enum.valueOf(Day.class, name);
    }

    // 私有構(gòu)造函數(shù),防止外部實(shí)例化
    private Day(String name, int ordinal) {
        super(name, ordinal);
    }
}

這解釋了幾個(gè)重要特性:

  1. 不能繼承: 因?yàn)?enum 已經(jīng)繼承了 Enum,Java 不允許多重繼承。
  2. 不能被繼承: enum 類默認(rèn)是 final 的。
  3. 內(nèi)置方法: values(), valueOf(String), ordinal(), name() 等方法由編譯器自動(dòng)生成。

四、 常用內(nèi)置方法

values(): 返回一個(gè)包含所有枚舉常量的數(shù)組,按它們聲明的順序排列。

Day[] days = Day.values();
for (Day day : days) {
    System.out.println(day); // 輸出 SUNDAY, MONDAY, ...
}

valueOf(String name): 根據(jù)字符串名稱返回對(duì)應(yīng)的枚舉常量。如果找不到匹配的名稱,則拋出 IllegalArgumentException。

Day day = Day.valueOf("MONDAY"); // 正確
// Day invalidDay = Day.valueOf("monday"); // 拋出 IllegalArgumentException,區(qū)分大小寫

name(): 返回枚舉常量的名稱(聲明時(shí)的字符串)。

System.out.println(Day.MONDAY.name()); // 輸出 "MONDAY"

ordinal(): 返回枚舉常量的序號(hào)(從0開(kāi)始)。

System.out.println(Day.MONDAY.ordinal()); // 輸出 1
System.out.println(Day.SATURDAY.ordinal()); // 輸出 6

注意: ordinal() 的值依賴于枚舉常量的聲明順序,如果順序改變,ordinal() 的值也會(huì)變。因此,除非有特殊需求(如序列化),否則應(yīng)盡量避免依賴 ordinal() 的值。

toString(): 默認(rèn)返回 name() 的值??梢员恢貙?。

五、 枚舉的高級(jí)用法:添加字段、構(gòu)造函數(shù)和方法

這是枚舉最強(qiáng)大的地方。我們可以為枚舉添加屬性、構(gòu)造函數(shù)和方法,使其不僅僅是簡(jiǎn)單的常量。

場(chǎng)景:訂單狀態(tài),每個(gè)狀態(tài)有其描述和是否為最終狀態(tài)的標(biāo)志。

public enum OrderStatus {
    PENDING("待支付", false),
    CONFIRMED("已確認(rèn)", false),
    SHIPPED("已發(fā)貨", false),
    DELIVERED("已送達(dá)", true), // 最終狀態(tài)
    CANCELLED("已取消", true); // 最終狀態(tài)

    // 構(gòu)造函數(shù)是私有的,防止外部實(shí)例化
    private final String description;
    private final boolean isFinal;

    // 枚舉的構(gòu)造函數(shù)只能是 private 或 package-private
    OrderStatus(String description, boolean isFinal) {
        this.description = description;
        this.isFinal = isFinal;
    }

    // Getter 方法
    public String getDescription() {
        return description;
    }

    public boolean isFinal() {
        return isFinal;
    }

    // 可以添加自定義方法
    public boolean canTransitionTo(OrderStatus newStatus) {
        // 簡(jiǎn)單的邏輯:不能從最終狀態(tài)轉(zhuǎn)換到其他狀態(tài)
        if (this.isFinal) {
            return false;
        }
        // 這里可以定義更復(fù)雜的業(yè)務(wù)規(guī)則,例如 PENDING -> CONFIRMED -> SHIPPED -> DELIVERED
        // 為了演示,這里只檢查目標(biāo)狀態(tài)是否為最終狀態(tài)
        return true; // 簡(jiǎn)化邏輯
    }
}

// 使用示例
public class OrderStatusDemo {
    public static void main(String[] args) {
        OrderStatus status = OrderStatus.PENDING;

        System.out.println("Status: " + status.name());
        System.out.println("Description: " + status.getDescription());
        System.out.println("Is Final: " + status.isFinal());

        System.out.println("Can transition from PENDING to CONFIRMED? " + status.canTransitionTo(OrderStatus.CONFIRMED));
        System.out.println("Can transition from DELIVERED to CANCELLED? " + OrderStatus.DELIVERED.canTransitionTo(OrderStatus.CANCELLED));
    }
}

另一個(gè)場(chǎng)景:HTTP 請(qǐng)求方法,每個(gè)方法有其含義。

public enum HttpMethod {
    GET("Retrieves information from the server"),
    POST("Submits data to be processed to the server"),
    PUT("Updates an existing resource on the server"),
    DELETE("Deletes a specified resource from the server");

    private final String meaning;

    HttpMethod(String meaning) {
        this.meaning = meaning;
    }

    public String getMeaning() {
        return meaning;
    }

    // 可以重寫 toString 方法,提供更有意義的字符串表示
    @Override
    public String toString() {
        return name() + ": " + meaning;
    }
}

// 使用示例
HttpMethod method = HttpMethod.POST;
System.out.println(method); // 輸出 "POST: Submits data to be processed to the server"

六、 枚舉中的抽象方法和具體實(shí)現(xiàn)

有時(shí),不同枚舉實(shí)例需要執(zhí)行不同的行為。這時(shí)可以在枚舉中定義抽象方法,然后讓每個(gè)實(shí)例提供具體的實(shí)現(xiàn)。

場(chǎng)景:操作類型(加、減、乘、除),每種操作有不同的計(jì)算邏輯。

public enum Operation {
    PLUS {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    MINUS {
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    },
    TIMES {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE {
        @Override
        public double apply(double x, double y) {
            if (y == 0) throw new ArithmeticException("Cannot divide by zero");
            return x / y;
        }
    };

    // 定義抽象方法
    public abstract double apply(double x, double y);
}

// 使用示例
public class Calculator {
    public static void main(String[] args) {
        Operation op = Operation.PLUS;
        double result = op.apply(4.0, 5.0);
        System.out.println(result); // 輸出 9.0

        op = Operation.DIVIDE;
        result = op.apply(10.0, 2.0);
        System.out.println(result); // 輸出 5.0
    }
}

七、 枚舉實(shí)現(xiàn)接口

枚舉類可以實(shí)現(xiàn)一個(gè)或多個(gè)接口。

interface Named {
    String getName();
}

interface Describable {
    String getDescription();
}

public enum Planet implements Named, Describable {
    MERCURY("Mercury", "The smallest planet"),
    VENUS("Venus", "The hottest planet"),
    EARTH("Earth", "Our home planet");

    private final String name;
    private final String description;

    Planet(String name, String description) {
        this.name = name;
        this.description = description;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return description;
    }
}

八、 實(shí)戰(zhàn)技巧與最佳實(shí)踐

  1. 命名規(guī)范: 枚舉類名通常采用名詞或名詞短語(yǔ),如 Color, Planet, ResponseStatus。枚舉常量通常使用全大寫字母和下劃線,如 RED, BLUE, SUCCESS, ERROR
  2. 不可變性: 枚舉實(shí)例通常是不可變的。確保所有字段都是 final 的,或者提供 setter 方法。
  3. 謹(jǐn)慎使用 ordinal(): 如前所述,ordinal() 的值與聲明順序耦合,容易導(dǎo)致維護(hù)問(wèn)題。
  4. 使用 switch: 在需要根據(jù)不同枚舉值執(zhí)行不同邏輯時(shí),switch 語(yǔ)句是一個(gè)很好的選擇。IDE 通常會(huì)提示你覆蓋所有可能的枚舉值,有助于代碼完整性。
  5. valueOf 的異常處理: 調(diào)用 valueOf 時(shí),必須考慮到傳入的字符串可能不存在對(duì)應(yīng)的枚舉值,因此要捕獲 IllegalArgumentException
try {
    OrderStatus status = OrderStatus.valueOf(inputStatusString.toUpperCase());
    // ...
} catch (IllegalArgumentException e) {
    System.err.println("Invalid status: " + inputStatusString);
    // 處理無(wú)效輸入
}
  1. 序列化: 枚舉類型天生支持序列化,反序列化時(shí)不會(huì)創(chuàng)建新實(shí)例,而是返回原有的單例,這保證了單例模式的安全性。

九、 總結(jié)

Java 的 enum 是一個(gè)強(qiáng)大而靈活的特性,它不僅僅是一組常量,更是一個(gè)功能完備的類。通過(guò)添加字段、方法、構(gòu)造函數(shù)甚至抽象方法,我們可以構(gòu)建出類型安全、功能豐富且易于維護(hù)的代碼結(jié)構(gòu)。掌握枚舉的用法,對(duì)于編寫高質(zhì)量的 Java 程序至關(guān)重要。

以上就是Java枚舉(Enum)從基礎(chǔ)到高級(jí)應(yīng)用詳解的詳細(xì)內(nèi)容,更多關(guān)于Java枚舉(Enum)詳解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用SpringBoot內(nèi)置web服務(wù)器

    使用SpringBoot內(nèi)置web服務(wù)器

    這篇文章主要介紹了使用SpringBoot內(nèi)置web服務(wù)器操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • spring boot項(xiàng)目如何采用war在tomcat容器中運(yùn)行

    spring boot項(xiàng)目如何采用war在tomcat容器中運(yùn)行

    這篇文章主要介紹了spring boot項(xiàng)目如何采用war在tomcat容器中運(yùn)行呢,主要講述將SpringBoot打成war包并放入tomcat中運(yùn)行的方法分享,需要的朋友可以參考下
    2022-11-11
  • Java如何實(shí)現(xiàn)可折疊Panel方法示例

    Java如何實(shí)現(xiàn)可折疊Panel方法示例

    這篇文章主要給大家介紹了關(guān)于利用Java如何實(shí)現(xiàn)可折疊Panel的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • Java Map的幾種循環(huán)方式總結(jié)

    Java Map的幾種循環(huán)方式總結(jié)

    這篇文章主要是對(duì)Java中Map的幾種循環(huán)方式進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-12-12
  • JAVA CountDownLatch與thread-join()的區(qū)別解析

    JAVA CountDownLatch與thread-join()的區(qū)別解析

    這篇文章主要介紹了JAVA CountDownLatch與thread-join()的區(qū)別解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Java分析講解序列化與字典功能的序列化

    Java分析講解序列化與字典功能的序列化

    在項(xiàng)目開(kāi)發(fā)地過(guò)程中經(jīng)常會(huì)用到字典存儲(chǔ)某些可配置的值,但相應(yīng)的也會(huì)給開(kāi)發(fā)帶來(lái)復(fù)雜度,比如數(shù)據(jù)庫(kù)存儲(chǔ)的值為字典值:0,1,2,3這種類型的值,但是前端頁(yè)面卻需要展示為 啟動(dòng)、禁用、刪除 等中文狀態(tài),下面我們來(lái)看兩種解決方案
    2022-06-06
  • JavaEE SpringMVC 請(qǐng)求傳參的示例詳解

    JavaEE SpringMVC 請(qǐng)求傳參的示例詳解

    這篇文章詳細(xì)介紹了SpringMVC中請(qǐng)求參數(shù)的傳遞和接收方式,包括傳遞單個(gè)參數(shù)、多個(gè)參數(shù)、對(duì)象參數(shù)、數(shù)組參數(shù)、集合參數(shù)以及JSON數(shù)據(jù)的傳遞和處理,感興趣的朋友一起看看吧
    2025-02-02
  • SpringCloud自定義loadbalancer實(shí)現(xiàn)標(biāo)簽路由的詳細(xì)方案

    SpringCloud自定義loadbalancer實(shí)現(xiàn)標(biāo)簽路由的詳細(xì)方案

    本文介紹了通過(guò)標(biāo)簽路由解決前端開(kāi)發(fā)環(huán)境接口調(diào)用慢的問(wèn)題,實(shí)現(xiàn)方案包括在本地服務(wù)注冊(cè)元數(shù)據(jù)、自定義負(fù)載均衡器、以及網(wǎng)關(guān)配置等步驟,通過(guò)環(huán)境變量設(shè)置標(biāo)簽,網(wǎng)關(guān)根據(jù)請(qǐng)求頭中的標(biāo)簽進(jìn)行路由,從而實(shí)現(xiàn)前后端互不干擾的開(kāi)發(fā)調(diào)試,感興趣的朋友一起看看吧
    2025-02-02
  • IDEA?2021.3?使用及idea2021.3.1激活使用方法

    IDEA?2021.3?使用及idea2021.3.1激活使用方法

    IDEA?全稱?IntelliJ?IDEA,是java語(yǔ)言開(kāi)發(fā)的集成環(huán)境,IntelliJ在業(yè)界被公認(rèn)為最好的java開(kāi)發(fā)工具之一,今天通過(guò)本文給大家介紹idea2021.3.1激活及使用教程,感興趣的朋友一起看看吧
    2022-01-01
  • Java Exchanger并發(fā)類使用方法

    Java Exchanger并發(fā)類使用方法

    這篇文章主要介紹了Java Exchanger并發(fā)類使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論

鄂州市| 屏山县| 历史| 平南县| 姜堰市| 本溪市| 永新县| 富顺县| 孝义市| 永丰县| 怀宁县| 彭泽县| 郴州市| 长沙市| 台山市| 龙陵县| 蒙阴县| 班玛县| 永丰县| 曲松县| 大连市| 新乡县| 天气| 东乡县| 宁武县| 怀来县| 电白县| 婺源县| 宜宾县| 洛宁县| 资源县| 行唐县| 平顶山市| 郯城县| 青冈县| 棋牌| 邵武市| 积石山| 南宁市| 古浪县| 泸定县|