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

Java?枚舉的定義、使用詳解

 更新時(shí)間:2025年12月31日 11:18:03   作者:楠枬  
本文介紹了Java中的枚舉(enum)概念,包括枚舉的定義、使用和常用方法,枚舉是一種特殊的類,用于定義一組常量,使得代碼更具有可讀性和可維護(hù)性,枚舉類默認(rèn)繼承自java.lang.Enum類,且不能被繼承,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

枚舉是什么

枚舉(enum):是一種特殊的類,用于定義一組常量,將其組織起來(lái)。枚舉使得代碼更具有可讀性和可維護(hù)性,特別是在處理固定集合的值時(shí),如:星期、月份、狀態(tài)碼等

在 Java 中,使用關(guān)鍵字 enum 來(lái)定義枚舉類:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}

其中,定義的枚舉項(xiàng)就是該類的實(shí)例,且必須在第一行,最后一個(gè)枚舉項(xiàng)后的分號(hào); 可以省略,但是若枚舉類有其他內(nèi)容,則分號(hào)不能省略(最好不要省略) 

當(dāng)類初始化時(shí),這些枚舉項(xiàng)就會(huì)被實(shí)例化

枚舉類使用 enum 定義后,默認(rèn)繼承 java.lang.Enum 類,也就是說(shuō),我們自己寫的枚舉類,就算沒(méi)有顯示的繼承 Enum,但是其默認(rèn)繼承了這個(gè)類

此外,枚舉在 Java 中不能被繼承,自定義的枚舉類隱式繼承自 java.lang.Enum 類,且不能再繼承其他類,這樣的設(shè)計(jì)確保了枚舉類的簡(jiǎn)單性和一致性。如果枚舉可以繼承其他類,將會(huì)導(dǎo)致復(fù)雜的繼承關(guān)系,并且影響Java的類型系統(tǒng)

常用方法

方法描述
values()以數(shù)組的形式返回枚舉類型的所有成員

ordinal()

獲取枚舉成員的索引位置
valueOf()將普通字符串轉(zhuǎn)換為枚舉實(shí)例

compareTo(E o)

比較兩個(gè)枚舉成員在定義時(shí)的順序

 我們通過(guò)一個(gè)示例,來(lái)學(xué)習(xí)和使用這些方法:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
    public static void main(String[] args) {
        // 獲取所有枚舉成員
        Day[] days = Day.values();
        // 遍歷
        for (int i = 0; i < days.length; i++) {
            // 獲取枚舉成員以及索引位置
            System.out.println(days[i] + " " + days[i].ordinal());
        }
        // 將普通字符串轉(zhuǎn)換為枚舉實(shí)例
        System.out.println(Day.valueOf("THURSDAY"));
        // 獲取枚舉實(shí)例 SUNDAY 和 SATURDAY
        Day sunday = Day.SUNDAY;
        Day saturday = Day.SATURDAY;
        // 比較定義時(shí)的順序
        System.out.println(sunday.compareTo(saturday));
    }
}

運(yùn)行結(jié)果:

在使用 valueOf() 方法進(jìn)行轉(zhuǎn)換時(shí),傳遞的名稱必須與枚舉常量的名字完全匹配(包括大小寫),若不匹配,就會(huì)拋出 IllegalArgumentException 異常:

 當(dāng)我們查看 java.lang.Enum 時(shí):

可以看到,valueOf() 方法包含了兩個(gè)類型的參數(shù):Class<T> enumClass  和  String name

其中

Class<T> enumType 是一個(gè) Class 對(duì)象,表示要查找的枚舉類型

String name: 是一個(gè)字符串,表示要查找的枚舉常量的名稱。名稱必須與枚舉常量的名字完全匹配(包括大小寫)

 但是在使用時(shí),我們只傳遞了一個(gè)參數(shù) name,也能夠進(jìn)行轉(zhuǎn)換,這是為什么呢?

這是因?yàn)?,?Java 中,valueOf 方法實(shí)際上是自動(dòng)生成的,屬于每個(gè)枚舉類型的特性。雖然它的原始定義需要兩個(gè)參數(shù)(類類型和名稱),但是每個(gè)枚舉類型都會(huì)自動(dòng)提供一個(gè)與自身類型相關(guān)聯(lián)的 valueOf 方法,只需傳遞一個(gè)字符串參數(shù)

因此,當(dāng)我們調(diào)用 Day.valueOf("THURSDAY") 時(shí),Java會(huì)自動(dòng)處理這個(gè)調(diào)用,實(shí)際調(diào)用的是包含類名的 valueOf 方法,而不是原始的靜態(tài)方法定義

再觀察 java.lang.Enum:

我們會(huì)發(fā)現(xiàn),其中并不存在 values() 這個(gè)方法,而當(dāng)我們點(diǎn)擊 values() 方法時(shí),則會(huì)跳轉(zhuǎn)到本類上

那么,values() 方法是從哪來(lái)的呢?

values() 方法是枚舉類自動(dòng)提供的一個(gè)靜態(tài)方法,允許我們獲取一個(gè)包含所有枚舉常量的數(shù)組,這個(gè)方法是由Java編譯器自動(dòng)生成的,在編譯時(shí)每個(gè)枚舉類型都會(huì)自動(dòng)生成一個(gè) values() 方法,因此不需要我們顯式定義它

我們將枚舉類進(jìn)行反編譯:

(1)打開 cmd,切換到 Day.java 文件所在目錄

(2)編譯 .java 文件(javac Day.java)

(3)將 .class 文件進(jìn)行反編譯(javap -c Day.class > day.txt)

打開 day.txt,可以看到:

編譯器自動(dòng)為我們生成了 values 和 valueOf 方法

構(gòu)造方法

當(dāng)我們創(chuàng)建構(gòu)造方法時(shí):

 不能使用 public 來(lái)修飾構(gòu)造方法,為什么呢?

這是因?yàn)?,?Java 中,枚舉類的構(gòu)造方法都是私有的(不加任何修飾符時(shí),默認(rèn)是 private),無(wú)法在枚舉類外部調(diào)用,這也就防止了在枚舉類外部創(chuàng)建新的枚舉常量

在定義枚舉常量時(shí),構(gòu)造方法會(huì)被隱式調(diào)用:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
    Day() {
        System.out.println("構(gòu)造方法");
    }
    public static void main(String[] args) {
        System.out.println("------------------");
    }
}

運(yùn)行結(jié)果: 

 當(dāng)我們定義帶有參數(shù)的構(gòu)造方法時(shí),在創(chuàng)建枚舉項(xiàng)時(shí),也要為其提供對(duì)應(yīng)參數(shù):

public enum Day {
    SUNDAY("周天", 7),
    MONDAY("周一", 1),
    TUESDAY("周二", 2),
    WEDNESDAY("周三", 3),
    THURSDAY("周四", 4),
    FRIDAY("周五", 5),
    SATURDAY("周六", 6);
    private String name;
    private int key;
    Day(String name, int key) {
        this.name = name;
        this.key = key;
    }
}

枚舉的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

(1)枚舉常量確保了只能使用定義的常量,避免了使用整型常量時(shí)可能帶來(lái)的錯(cuò)誤

(2)使用枚舉可以使代碼更易讀,表達(dá)清晰

(3)枚舉定義了一組固定的常量,適合表示有限的狀態(tài)或選項(xiàng),便于管理和維護(hù)

(4)枚舉可以擁有字段、方法和構(gòu)造方法,能夠封裝與常量相關(guān)的行為和屬性

(5)Java的枚舉類自帶一些方法,如 values()、valueOf() 等

(6)可以用于 switch 語(yǔ)句

缺點(diǎn):

(1)枚舉的集合是固定的,無(wú)法在運(yùn)行時(shí)添加或刪除常量。如果需要?jiǎng)討B(tài)的集合,枚舉可能不適用

(2)枚舉不能繼承,無(wú)法擴(kuò)展

(3)每個(gè)枚舉常量都是一個(gè)對(duì)象,可能會(huì)增加內(nèi)存使用,特別是當(dāng)枚舉常量數(shù)量較多時(shí)

枚舉和反射

 Java 反射 中,我們學(xué)習(xí)了反射,通過(guò)反射,我們可以拿到類的私有構(gòu)造方法,從而創(chuàng)建實(shí)例對(duì)象

那么,枚舉是否可以通過(guò)反射,拿到實(shí)例對(duì)象呢?

public enum Day {
    SUNDAY("周天", 7),
    MONDAY("周一", 1),
    TUESDAY("周二", 2),
    WEDNESDAY("周三", 3),
    THURSDAY("周四", 4),
    FRIDAY("周五", 5),
    SATURDAY("周六", 6);
    private String name;
    private int key;

    Day(String name, int key) {
        this.name = name;
        this.key = key;
    }
}
public class Test {
    public static void main(String[] args) {
        Class<?> classDay = null;
        try {
            classDay = Class.forName("Day");
            Constructor<?> constructor = classDay.getDeclaredConstructor(String.class, int.class);
            constructor.setAccessible(true);
            Day day = (Day) constructor.newInstance("sunday", 0);
            System.out.println(day.ordinal());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

運(yùn)行結(jié)果:

此時(shí)程序拋出了 NoSuchMethodException 異常,也就是沒(méi)有對(duì)應(yīng)的構(gòu)造方法

但是提供的枚舉的構(gòu)造方法就是帶有兩個(gè)參數(shù),分別為 String 和 int:

那么,問(wèn)題出在哪里呢?

自定義的枚舉類默認(rèn)繼承自 java.lang.Enum

因此,自定義的枚舉類繼承了父類除構(gòu)造方法外的所有東西,且子類需要幫助父類進(jìn)行構(gòu)造,

但我們實(shí)現(xiàn)的類中,并沒(méi)有幫助父類進(jìn)行構(gòu)造

因此,我們需要在枚舉類中幫助父類進(jìn)行構(gòu)造,而父類中的構(gòu)造方法為:

那么,如何實(shí)現(xiàn)呢?通過(guò) super 方法嗎?

但是,當(dāng)我們?cè)跇?gòu)造方法中調(diào)用 super 時(shí):

枚舉構(gòu)造方法中不能使用 super

 由于枚舉比較特殊,在構(gòu)造方法中,除了我們自定義了兩個(gè)參數(shù),它還默認(rèn)添加了父類的兩個(gè)參數(shù)

也就是說(shuō),構(gòu)造函數(shù)中一共有四個(gè)參數(shù):String int String int

其中,前兩個(gè)參數(shù)是父類參數(shù),后兩個(gè)參數(shù)是子類參數(shù)

public class Test {
    public static void main(String[] args) {
        Class<?> classDay = null;
        try {
            classDay = Class.forName("enumDemo.Day");
            Constructor<?> constructor = classDay.getDeclaredConstructor(String.class, int.class, String.class, int.class);
            constructor.setAccessible(true);
            Day day = (Day) constructor.newInstance("父類參數(shù)", 0, "子類參數(shù)", 0);
            System.out.println(day.ordinal());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

再次運(yùn)行:

此時(shí)拋出了 IllegalArgumentException 異常,不能通過(guò)反射創(chuàng)建枚舉對(duì)象

枚舉保證了每個(gè)枚舉常量只有一個(gè)實(shí)例,這種唯一性在枚舉類型被定義時(shí)就已經(jīng)確定,不允許外部創(chuàng)建新的實(shí)例,枚舉類型的設(shè)計(jì)使得它們的實(shí)例在類加載時(shí)被唯一地定義,從而避免了通過(guò)反射創(chuàng)建新的枚舉實(shí)例的可能性,確保了枚舉的強(qiáng)類型安全性和唯一性

實(shí)現(xiàn)單例模式

在 單例模式:餓漢模式、懶漢模式_單例模式懶漢和餓漢-CSDN博客 中我們實(shí)現(xiàn)了單例模式,單例模式能夠確保一個(gè)類只有一個(gè)實(shí)例

但普通類可以通過(guò)反射機(jī)制打破,因此,我們可以使用枚舉來(lái)實(shí)現(xiàn)單例模式

public enum Singleton {
    INSTANCE;
    public Singleton getInstance() {
        return INSTANCE;
    }
}

到此這篇關(guān)于Java 枚舉的定義、使用詳解的文章就介紹到這了,更多相關(guān)Java 枚舉內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 數(shù)據(jù)結(jié)構(gòu)并查集詳解

    java 數(shù)據(jù)結(jié)構(gòu)并查集詳解

    并查集是一種用來(lái)管理元素分組情況的數(shù)據(jù)結(jié)構(gòu)。并查集可以高效地進(jìn)行如下操作。本文將通過(guò)Java實(shí)現(xiàn)并查集,感興趣的小伙伴可以了解一下
    2022-03-03
  • openGauss數(shù)據(jù)庫(kù)JDBC環(huán)境連接配置的詳細(xì)過(guò)程(Eclipse)

    openGauss數(shù)據(jù)庫(kù)JDBC環(huán)境連接配置的詳細(xì)過(guò)程(Eclipse)

    這篇文章主要介紹了openGauss數(shù)據(jù)庫(kù)JDBC環(huán)境連接配置(Eclipse),演示基于JDBC開發(fā)的主要步驟,會(huì)涉及創(chuàng)建數(shù)據(jù)庫(kù)、創(chuàng)建表、插入數(shù)據(jù)等,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Java 異常java.lang.NoSuchFieldException解決方案

    Java 異常java.lang.NoSuchFieldException解決方案

    這篇文章主要介紹了Java 異常java.lang.NoSuchFieldException解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • mybatis-plus 關(guān)于savebatch,saveorupdatebatch遇到的坑及解決辦法

    mybatis-plus 關(guān)于savebatch,saveorupdatebatch遇到的坑及解決辦法

    本文主要介紹了mybatis-plus 關(guān)于savebatch,saveorupdatebatch遇到的坑及解決辦法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • SpringBoot 關(guān)于Feign的超時(shí)時(shí)間配置操作

    SpringBoot 關(guān)于Feign的超時(shí)時(shí)間配置操作

    這篇文章主要介紹了SpringBoot 關(guān)于Feign的超時(shí)時(shí)間配置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 基于Java Tomcat和激活MyEclips的深入理解

    基于Java Tomcat和激活MyEclips的深入理解

    本篇文章是對(duì)Java中的Tomcat和激活MyEclips進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 超細(xì)講解Java調(diào)用python文件的幾種方式

    超細(xì)講解Java調(diào)用python文件的幾種方式

    有時(shí)候我們?cè)趯慾ava的時(shí)候需要調(diào)用python文件,下面這篇文章主要給大家介紹了關(guān)于Java調(diào)用python文件的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 解決idea反編譯失敗無(wú)法查看jar包的源碼問(wèn)題

    解決idea反編譯失敗無(wú)法查看jar包的源碼問(wèn)題

    在IntelliJ IDEA中查看jar包源碼的兩種方法:下載反編譯軟件JD-GUI或安裝JavaBytecodeDecompiler插件
    2024-12-12
  • Java簡(jiǎn)單實(shí)現(xiàn)UDP和TCP的示例

    Java簡(jiǎn)單實(shí)現(xiàn)UDP和TCP的示例

    下面小編就為大家?guī)?lái)一篇Java簡(jiǎn)單實(shí)現(xiàn)UDP和TCP的示例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Java 內(nèi)省introspector相關(guān)原理代碼解析

    Java 內(nèi)省introspector相關(guān)原理代碼解析

    這篇文章主要介紹了Java 內(nèi)省introspector相關(guān)原理代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評(píng)論

玛曲县| 绥中县| 郑州市| 芒康县| 白银市| 班玛县| 嘉善县| 东辽县| 莒南县| 平武县| 芒康县| 开封县| 清苑县| 巫山县| 樟树市| 玉田县| 信宜市| 阿勒泰市| 安多县| 泰和县| 锡林浩特市| 廉江市| 即墨市| 子洲县| 文成县| 都江堰市| 雷波县| 满城县| 福州市| 廊坊市| 寿光市| 福泉市| 东乡| 沂南县| 澄迈县| 伊宁县| 建昌县| 嘉兴市| 大余县| 成武县| 永顺县|