java java.lang.enum_源碼閱讀-java基礎-java.lang.Enum

1、引言

枚舉類型是 JDK 5 之后引進的一種非常重要的引用類型,可以用來定義一系列枚舉常量。相比與常量(public static final定義),在安全性、指意性、可讀性方面更勝一籌。另外它可以和switch case搭配使用。

2、類定義

實際上在使用關鍵字enum創建枚舉類型并編譯后,編譯器會為我們生成一個相關的類,這個類繼承了Java API中的java.lang.Enum類,也就是說通過關鍵字enum創建枚舉類型在編譯后事實上也是一個類類型而且該類繼承自java.lang.Enum類,并且該類類型是final修飾的,無法被繼承。

public abstract class Enum>implements Comparable, Serializable {}

3、成員屬性

// 枚舉常量的名稱

private final String name;

// 它和不重寫的toString()方法返回的是一樣的,只不過toString()方法可以進行重寫定制。

public final String name() {

return name;

}

/**

* 枚舉常量的序號(它在枚舉聲明中的位置,其中初始常量的序號為零)。

* 代碼中盡量避免使用該值,因為我們有時候添加新枚舉時,總是“按組”放在一起,不會放到最后,除非強制要求。

* 比如接口響應碼的枚舉,我們通常會把參數異常的放一組,內部異常的放一組等。如果參數異常新添加一個枚舉“xx不存在”,如果這個枚舉沒有放在整個接口響應碼枚舉的末尾,而是放到了某一組的末尾,那么部分枚舉常量的ordinal值就發生了變化。這將是災難性的,所以要么代碼規范添加新枚舉只能添加到末尾;要么不使用該值。

*/

private final int ordinal;

public final int ordinal() {

return ordinal;

}

4、構造方法

// 唯一的構造方法,程序員調用不到,它由編譯器發出的代碼用于響應枚舉類型聲明。

protected Enum(String name, int ordinal) {

this.name = name;

this.ordinal = ordinal;

}

5、其他方法

// 返回聲明中包含的此枚舉常量的名稱。 可以覆蓋該方法,但通常不需要或不需要。

public String toString() {

return name;

}

public final boolean equals(Object other) {

return this==other;

}

// 這里調用的是Object的hashCode方法

public final int hashCode() {

return super.hashCode();

}

// 不能克隆,保證了枚舉永遠是單例的,所以枚舉是單例模式的典型代表

protected final Object clone() throws CloneNotSupportedException {

throw new CloneNotSupportedException();

}

// 這里需要注意,底層的實現用的是ordinal實現的,即比較的是枚舉常量的序號。

public final int compareTo(E o) {

Enum> other = (Enum>)o;

Enum self = this;

if (self.getClass() != other.getClass() &&

self.getDeclaringClass() != other.getDeclaringClass())

throw new ClassCastException();

return self.ordinal - other.ordinal;

}

// 返回與此枚舉常量的枚舉類型相對應的 Class 對象。

public final Class getDeclaringClass() {

Class> clazz = getClass();

Class> zuper = clazz.getSuperclass();

return (zuper == Enum.class) ? (Class)clazz : (Class)zuper;

}

// 枚舉不能有finalize方法

protected final void finalize() { }

/**

* 防止默認反序列化

*/

private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {

throw new InvalidObjectException("can't deserialize enum");

}

private void readObjectNoData() throws ObjectStreamException {

throw new InvalidObjectException("can't deserialize enum");

}

/**

* 返回簡單名稱到枚舉常量的映射。

* name的值必須與用于聲明此類型的枚舉常量的標識符完全一致。

*

* 對于特定的枚舉類型T,有兩個隱式聲明的方法可以直接使用:

* 1) public static T valueOf(String) 根據名稱獲取單個枚舉類型;這個我深有體會,因為之前是不知道有這個方法,通常是用values()獲取枚舉集合map,然后遍歷

* 2) public static T[] values() 獲取所有枚舉類型數組;

*/

public static > T valueOf(Class enumType,String name) {

T result = enumType.enumConstantDirectory().get(name);

if (result != null)

return result;

if (name == null)

throw new NullPointerException("Name is null");

throw new IllegalArgumentException(

"No enum constant " + enumType.getCanonicalName() + "." + name);

}

/**

* 1)該方法是屬于java.lang.Class,不是java.lang.Enum的方法;

* 2)enumConstantDirectory 是一個map,定義如下:private volatile transient Map enumConstantDirectory = null;其中key為枚舉的name,value為枚舉。

* 3)enumConstantDirectory()方法獲取枚舉常量目錄,沒有就繼續調用getEnumConstantsShared();如果有返回值,就遍歷put進enumConstantDirectory。

*/

Map enumConstantDirectory() {

if (enumConstantDirectory == null) {

T[] universe = getEnumConstantsShared();

if (universe == null)

throw new IllegalArgumentException(

getName() + " is not an enum type");

Map m = new HashMap<>(2 * universe.length);

for (T constant : universe)

m.put(((Enum>)constant).name(), constant);

enumConstantDirectory = m;

}

return enumConstantDirectory;

}

7、枚舉隱式實現的方法

如上所說,枚舉自動繼承這兩個隱式方法。這兩個方法很重要,所以我在這里單拎出來了。

// 根據名稱獲取單個枚舉類型

public static T valueOf(String){}

// 獲取所有枚舉類型數組

public static T[] values(){}

8、枚舉集合

這兩個是枚舉優化過后的集合,比HashSet,HashMap的性能更高。

8.1、EnumSet

8.2、EnumMap

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/531727.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/531727.shtml
英文地址,請注明出處:http://en.pswp.cn/news/531727.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java中有關線程的題目

1&#xff0c;看一下下面程序錯誤發生在哪一行&#xff01; class Test implements Runnable{public void run(Thread t){} }2&#xff0c;輸出結果是什么&#xff1f; class Test{public static void main(String[] args){new Thread(new Runnable(){public void run(){System…

java 可逆的加密算法_java實現AES可逆加密算法

package com.hdu.encode;import javax.crypto.Cipher;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import sun.misc.BASE64Decoder;import sun.misc.BASE64Encoder;/*** AES 是一種可逆加密算法&#xff0c;對用戶的敏感信息加密處理 對…

森林轉換成二叉樹以及二叉樹還原為森林代碼

1 /*2 森林轉換成二叉樹3 思路&#xff1a;u的孩子節點為v1, v2, v3....&#xff08;v1,v2,....互為兄弟節點&#xff09; 4 那么將u的一個孩子節點&#xff08;v1&#xff09;連在u的左子樹上&#xff0c;那么其他的孩子節點都連在v1的右子樹上&#xff01; 5 …

poj1062昂貴的聘禮(Dijkstra**)

1 /*2 題意&#xff1a; 物主有一個物品&#xff0c;價值為P&#xff0c;地位為L&#xff0c; 以及一系列的替代品Ti和該替代品所對應的"優惠"Vi3 g[u][i] 表示的是u物品被i物品替換后的優惠價格&#xff01;(u>0, i>0)4 g[u][0]表示不用替換該物品的…

java openmp庫_OpenMP的環境變量及庫函數

OpenMP的環境變量&#xff1a;環境變量 描述 示例OMP_SCHEDULE 控制for循環任務分配結構的調度 OMP_SCHEDULE"guided,2"OMP_NUM_THREADS 設置默認線程的個數 OMP_SCHEDULE4OpenMP的庫函數函數名稱 描述int omp_get_num_threads(void) 返回當前使用的線程個數&#xf…

hdu1269迷宮城堡(判斷有向圖是否是一個強連通圖)

1 /* 題意&#xff1a; 給你一個圖&#xff0c;求這個有向圖示否是一個強連通圖&#xff08;每兩個節點都是可以相互到達的&#xff09;&#xff01; 思路1&#xff1a;按正向邊dfs一遍&#xff0c;將經過的節點計數&#xff0c;如果記錄的節點的個數小于…

mgg mysql_mgg文件怎么轉換mp3格式?

步驟/方法方法/步驟1:下載載視頻轉換器&#xff0c;我們說到在官網下載比較好吧。下載完成之后&#xff0c;我們就直接點擊進行安裝&#xff0c;一般 在安裝的過程也是非常快速的&#xff0c;主要是按照安裝向導上的步驟進行就可以了。方法/步驟2:安裝好之后&#xff0c;我們就…

poj 2385Apple Catching(簡單dp)

1 /*2 題意&#xff1a; 有兩棵蘋果樹&#xff0c;每一棵蘋果樹每一秒間隔的掉落下來一個蘋果&#xff0c;一個人在樹下接住蘋果&#xff0c;不讓蘋果掉落&#xff01;3 人在兩棵樹之間的移動是很快的&#xff01;但是這個人移動的次數是有限制的&#xff0c;問最多可以…

java dao 泛型的好處_java中泛型有什么作用

泛型的作用如下&#xff1a;1、類型安全泛型的主要目標是提高 Java 程序的類型安全。編譯時的強類型檢查&#xff1b;通過知道使用泛型定義的變量的類型限制&#xff0c;編譯器可以在一個高得多的程度上驗證類型假設。沒有泛型&#xff0c;這些假設就只存在于程序員的頭腦中(或…

poj3249Test for Job(記憶化搜索)

1 /*2 題意&#xff1a;給一個DAG圖&#xff0c;n個節點&#xff0c;每個節點都對應一個值&#xff0c;入度為零的點走到出度為零的點&#xff0c;計算所有可能路徑3 經過節點值的和最大&#xff01;4 5 思路&#xff1a;記憶話搜索&#xff1a;也就是如果我們搜索…

Java兩同_java:一個類實現的兩個接口里都有同一個方法(名),怎么處理?

不一定&#xff0c;關鍵要看子類是否是抽象類。如果子類是非抽象類&#xff0c;則必須實現接口中的所有方法&#xff1b;如果子類是抽象類&#xff0c;則可以不實現接口中的所有方法&#xff0c;因為抽象類中允許有抽象方法的存在&#xff01;1、抽象類定義抽象類往往用來表征對…

ZOJ3805Machine(二叉樹左右子樹變換)

1 /*2 題意&#xff1a;建立一棵二叉樹&#xff0c;左子樹和父節點占一個寬度&#xff0c;右子樹另外占一個寬度&#xff01;3 使任意左右子樹交換順序&#xff0c;使得整個樹的寬度最小&#xff01;4 思路&#xff1a;遞歸交換左右子樹 &#xff01; …

java ==和=_Java ==和equals()的區別

前言本篇文章講的是從JVM角度比較和equals的區別一&#xff1a;** Java數據類型分類**Paste_Image.png1&#xff1a;基本數據類型又稱為原始數據類型&#xff0c;他們之間的比較應該使用()&#xff0c;比較的是他們的值。2&#xff1a;引用數據類型當引用數據類型用()進行比較&…

ZOJ 3804 YY's Minions (簡單模擬)

1 /*2 題意&#xff1a;一個矩陣中有 n*m個寵物&#xff0c;每一個寵物都有一個狀態&#xff0c; 1醒著的&#xff0c;0睡著的3 X離開的&#xff01;如果這個寵物&#xff08;醒著的&#xff09;的周圍醒著的個數>3 || <2它就會睡著&#xff0c;4 如果這個寵物&…

java接口方法實現_Java接口的簡單定義與實現方法示例

本文實例講述了Java接口的簡單定義與實現方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;1、接口是Java中最終要的概念&#xff0c;接口可以理解為一種特殊的類&#xff0c;里面全部是由全局常量和公共的抽象方法所組成。2、接口的格式:interface interfaceName{全…

NYOJ995硬幣找零(簡單dp)

1 /*2 題意&#xff1a;給你不同面額的硬幣&#xff08;每種硬幣無限多&#xff09;&#xff0c;需要找零的面值是T&#xff0c;用這些硬幣進行找零&#xff0c;3 如果T恰好能被找零&#xff0c;輸出最少需要的硬幣的數目&#xff01;否則請輸出剩下錢數最少的找零方案…

docker mysql命令大全_Docker命令大全

Docker run 命令docker run [OPTIONS] IMAGE [COMMAND] [ARG...]OPTIONS說明&#xff1a;-a stdin: 指定標準輸入輸出內容類型&#xff0c;可選 STDIN/STDOUT/STDERR 三項&#xff1b;-d: 后臺運行容器&#xff0c;并返回容器ID&#xff1b;-i: 以交互模式運行容器&#xff0c;…

NYOJ 1023 還是回文(DP,花最少費用形成回文串)

1 /*2 題意&#xff1a;給出一串字符(全部是小寫字母)&#xff0c;添加或刪除一個字符&#xff0c;都會產生一定的花費。3 那么&#xff0c;將字符串變成回文串的最小花費是多少呢&#xff1f; 4 5 思路&#xff1a;如果一個字符串增加一個字符 x可以形成一個回文串…

java mapreduce教程_Java搭建MapReduce完成二次排序步驟

1、構建新的作業Configuration confgetConf();Job jobJob.getInstance(conf);job.setJarByClass(SortYearAndTemp2.class);2、設置輸入輸出目錄Path inpathnew Path(conf.get("inpath"));Path outpathnew Path(conf.get("outpath"));FileInputFormat.addIn…

contentprovider java_創建Contentprovider,

創建Contentprovider:1. 創建一個provider----ExampleContentProvidera. 設計authority b. 設計path c.處理content URI IDs d.Content URI patterns)定義MIME Types(One of the required methods that you must implement for any provider.A method that youre expected to i…