Java中枚舉的實(shí)現(xiàn)原理介紹
基本概述
在 JDK1.5 之前,通過(guò)定義常量使用的都是:public static fianl。而枚舉的設(shè)計(jì),就是把相關(guān)的常量分組到一個(gè)枚舉類型里,方便創(chuàng)建和管理。
比如我們要定義一個(gè)顏色常量:
public enum Colour {
RED, YELLOW, BLUE, GREEN
}
這段代碼通過(guò)底層編譯后,實(shí)際創(chuàng)建了4個(gè)枚舉對(duì)象:
new Enum<EnumTest>("RED", 0);
new Enum<EnumTest>("YELLOW", 1);
new Enum<EnumTest>("BLUE", 2);
new Enum<EnumTest>("GREEN", 3);
使用方式
條件選擇
enum 能通過(guò) switch 方法進(jìn)行簡(jiǎ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)遍歷
通過(guò)循環(huán)遍歷 .values() 能夠取到對(duì)象中的值
for (Colour e : Colour.values()) {
System.out.println(e.toString());
}
集合映射
在我們使用枚舉類型作為集合的類型或映射中的鍵的類型時(shí),可以使用專門(mén)且高效的集合和映射實(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());
}
常用方法
通過(guò) 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;
}
```
// 與指定的對(duì)象進(jìn)行比較以進(jìn)行排序,當(dāng)此對(duì)象小于、等于或大于指定對(duì)象時(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;
}
```
// 返回與此枚舉常量的枚舉類型對(duì)應(yīng)的 Class 對(duì)象。
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
}
```
## 底層原理
`enum` 的語(yǔ)法結(jié)構(gòu)可能對(duì)于正常的 Java 看起來(lái)怪怪的,但是通過(guò)編譯器編譯后產(chǎn)生的是一個(gè) `.class` 文件, 可以理解枚舉的語(yǔ)法結(jié)構(gòu)是一種規(guī)范,使編譯器能識(shí)別并轉(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è)類的形式存在,它能夠更加方便的幫助我們定義常量對(duì)象,并且支持定義屬性和方法,在一定程度上提高了我們的編程效率。
但是在使用時(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談Zookeeper開(kāi)源客戶端框架Curator
這篇文章主要介紹了淺談Zookeeper開(kāi)源客戶端框架Curator的相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10
Java開(kāi)發(fā)必備知識(shí)之?dāng)?shù)組詳解
數(shù)組對(duì)于每一門(mén)編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同.本篇文章為大家整理了Java最全關(guān)于數(shù)組的知識(shí)點(diǎn),并給出其對(duì)應(yīng)的代碼,需要的朋友可以參考下2021-06-06
解決mybatis-plus 查詢耗時(shí)慢的問(wèn)題
這篇文章主要介紹了解決mybatis-plus 查詢耗時(shí)慢的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java中main函數(shù)的String[]?args用法舉例詳解
這篇文章主要給大家介紹了關(guān)于Java中main函數(shù)的String[]?args用法的相關(guān)資料,JAVA類中main函數(shù)的參數(shù)String[]?args指的是運(yùn)行時(shí)給main函數(shù)傳遞的參數(shù),文中通過(guò)圖文以及代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
java rocketmq--消息的產(chǎn)生(普通消息)
這篇文章主要介紹了java rocketmq--消息的產(chǎn)生(普通消息),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下2019-06-06
Java操作redis設(shè)置第二天凌晨過(guò)期的解決方案
這篇文章主要介紹了Java操作redis設(shè)置第二天凌晨過(guò)期的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01

