Java中枚舉的實(shí)現(xiàn)原理介紹
基本概述
在 JDK1.5 之前,通過定義常量使用的都是:public static fianl
。而枚舉的設(shè)計(jì),就是把相關(guān)的常量分組到一個(gè)枚舉類型里,方便創(chuàng)建和管理。
比如我們要定義一個(gè)顏色常量:
public enum Colour { RED, YELLOW, BLUE, GREEN }
這段代碼通過底層編譯后,實(shí)際創(chuàng)建了4個(gè)枚舉對象:
new Enum<EnumTest>("RED", 0); new Enum<EnumTest>("YELLOW", 1); new Enum<EnumTest>("BLUE", 2); new Enum<EnumTest>("GREEN", 3);
使用方式
條件選擇
enum 能通過 switch
方法進(jìn)行簡單條件判斷
Colour color = Colour.RED; switch (color) { case RED: System.out.println("紅色"); break; case YELLOW: System.out.println("黃色"); break; case GREEN: System.out.println("綠色"); break; case BLUE: System.out.println("藍(lán)色"); break; default: System.out.println(color); break; }
循環(huán)遍歷
通過循環(huán)遍歷 .values()
能夠取到對象中的值
for (Colour e : Colour.values()) { System.out.println(e.toString()); }
集合映射
在我們使用枚舉類型作為集合的類型或映射中的鍵的類型時(shí),可以使用專門且高效的集合和映射實(shí)現(xiàn)。如: java.util.EnumSet
、 java.util.EnumMap
// EnumSet的使用 EnumSet<Colour> colorSet = EnumSet.allOf(Colour.class); for (Colour color : colorSet) { System.out.println(color); } // EnumMap的使用 EnumMap<Colour, String> colorMap = new EnumMap(Colour.class); colorMap.put(Colour.RED, "紅色"); colorMap.put(Colour.YELLOW, "黃色"); colorMap.put(Colour.GREEN, "綠色"); colorMap.put(Colour.BLUE, "藍(lán)色"); Set<Map.Entry<Colour, String>> colorEntries = colorMap.entrySet(); for (Map.Entry<Colour, String> entry : colorEntries) { System.out.println(entry.getKey().name() + ":" + entry.getValue()); }
常用方法
通過 java.lang.Enum
類的源碼,可以探索下枚舉常用的一些方法和設(shè)計(jì)思想:
// Enum 唯一的構(gòu)造函數(shù),由于 protected 修飾,所以不能調(diào)用這個(gè)構(gòu)造函數(shù)。 它供編譯器為響應(yīng)枚舉類型聲明而發(fā)出的代碼使用。 protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } ``` // 返回此枚舉常量的名稱,與在其枚舉聲明中聲明的完全相同。 public final String name() { return name; } ``` // 返回此枚舉常量的序數(shù)(它在枚舉聲明中的位置,其中初始常量被分配零序數(shù))。(但大多數(shù)程序員不會(huì)使用這種方法) public final int ordinal() { return ordinal; } ``` // 與指定的對象進(jìn)行比較以進(jìn)行排序,當(dāng)此對象小于、等于或大于指定對象時(shí),返回一個(gè)負(fù)整數(shù)、零或正整數(shù)。且只能與相同枚舉類型的其他枚舉常量進(jìn)行比較。 public final int compareTo(E o) { Enum<?> other = (Enum<?>)o; Enum<E> self = this; if (self.getClass() != other.getClass() self.getDeclaringClass() != other.getDeclaringClass()) throw new ClassCastException(); return self.ordinal - other.ordinal; } ``` // 返回與此枚舉常量的枚舉類型對應(yīng)的 Class 對象。 public final Class<E> getDeclaringClass() { Class<?> clazz = getClass(); Class<?> zuper = clazz.getSuperclass(); return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper; } ```
## 底層原理 `enum` 的語法結(jié)構(gòu)可能對于正常的 Java 看起來怪怪的,但是通過編譯器編譯后產(chǎn)生的是一個(gè) `.class` 文件, 可以理解枚舉的語法結(jié)構(gòu)是一種規(guī)范,使編譯器能識別并轉(zhuǎn)化為相應(yīng)的類,底層實(shí)際上還是 `class` 。 ```java public class com.project.demo.Colour extends java.lang.Enum{ public static final com.project.demo.Colour RED; public static final com.project.demo.Colour YELLOW; public static final com.project.demo.Colour BLUE; public static final com.project.demo.Colour GREEN; static {}; }
總結(jié)
所以 enum
實(shí)際上在 Java 只是一個(gè)類的形式存在,它能夠更加方便的幫助我們定義常量對象,并且支持定義屬性和方法,在一定程度上提高了我們的編程效率。
但是在使用時(shí)需要注意, enum
不能支持繼承,應(yīng)該它已經(jīng)繼承了包里的 java.lang.Enum
類,所以在程序設(shè)計(jì)時(shí)我們需要考慮到。
到此這篇關(guān)于Java中枚舉的實(shí)現(xiàn)原理介紹的文章就介紹到這了,更多相關(guān)Java枚舉實(shí)現(xiàn)原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+Mybatis實(shí)現(xiàn)登錄注冊的示例代碼
這篇文章主要介紹了SpringBoot+Mybatis實(shí)現(xiàn)登錄注冊的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Java設(shè)計(jì)模式之原型模式詳細(xì)解析
這篇文章主要介紹了Java設(shè)計(jì)模式之原型模式詳細(xì)解析,原型模式就是用一個(gè)已經(jīng)創(chuàng)建的實(shí)例作為原型,通過復(fù)制該原型對象來創(chuàng)建一個(gè)和原型對象相同的新對象,需要的朋友可以參考下2023-11-11Java詳細(xì)講解Math和Random類中有哪些常用方法
Math類位于java.lang包中,包含很多用于科學(xué)計(jì)算的類方法,這些方法可以直接通過類名調(diào)用。Random類獲取隨機(jī)數(shù),位于java.util包中,本篇帶你了解它們的常用方法2022-05-05解決Springboot項(xiàng)目bootstrap.yml不生效問題
Spring Boot 2.4版本開始,配置文件加載方式進(jìn)行了重構(gòu),只會(huì)識別application.* 配置文件,并不會(huì)自動(dòng)識別bootstrap.yml,所以本文給大家介紹Springboot項(xiàng)目bootstrap.yml不生效問題的解決方案,需要的朋友可以參考下2023-09-09淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度
這篇文章主要介紹了淺談Spring Cloud Netflix-Ribbon灰度方案之Zuul網(wǎng)關(guān)灰度,想了解Ribbon灰度的同學(xué)可以參考下2021-04-04Java synchronized關(guān)鍵字使用方式及特性解析
這篇文章主要介紹了Java synchronized關(guān)鍵字使用方式及特性解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12關(guān)于Mybatis動(dòng)態(tài)sql中test的坑點(diǎn)總結(jié)
這篇文章主要介紹了關(guān)于Mybatis動(dòng)態(tài)sql中test的坑點(diǎn),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01