Java枚舉(Enum)類型原理探求

2020-12-16 黑馬程式設計師

Enum枚舉類型

Enum的全寫是Enumeration,這個詞的翻譯是列舉、逐條陳述、細目。在程序語言中,枚舉類型是一種特殊的數據類型(常用的數據類型比如字符串、整型),這種數據類型的變量值限定在固定的範圍, 比如季節只有春夏秋冬,月份是12個。

Java中的枚舉

枚舉前時代

在Java語言中, 枚舉類型從JDK1.5才開始提供。在這之前使用接口靜態常量來實現相關功能(也可以是類靜態常量),以季節為例:

在不使用枚舉類之前,一般使用接口靜態常量實現。比如:

publicinterfaceSeason{ publicstaticfinalint SPRING = 1; publicstaticfinalint SUMMER = 2; publicstaticfinalint AUTUMN = 3; publicstaticfinalint WINTER = 4;}

使用JUnit使用測試如下:

@TestpublicvoidnoEnum(){ int i = 1; Assert.assertTrue(Season.SPRING==i);}

使用接口靜態常量的方式比較難限定變量的範圍,而且定義繁瑣,功能也很有限,於是在Java 1.5 中定義了一個枚舉類型:java.lang.Enum。

Java枚舉的定義

類似類(class)和接口(interface)的定義,Java提供enum關鍵字用來定義枚舉類,在IDEA中創建枚舉類的菜單如下:

同樣定義一個季節的枚舉類, 代碼可以簡潔如下:

package cn.osxm.jcodef.func.base;publicenum SeasonEnum { SPRING, SUMMER, AUTUMN, WINTER}

在枚舉類中直接列出常量,常量遵循全部大寫的規則。在上面的枚舉類示例代碼中,SPRING, SUMMER, AUTUMN, WINTER 是SeasonEnum的成員。

枚舉成員默認是final、public、static (所以可以使用SeasonEnum.SPRING方式調用枚舉成員)每一個枚舉類型成員都可以看作是枚舉類的實例 (SeasonEnum.SPRING的類型也是SeasonEnum)在JUnit使用測試如下:

@Test publicvoidenumBase() { SeasonEnum season = SeasonEnum.SPRING; Assert.assertTrue(season.equals(SeasonEnum.SPRING)); }

Java 枚舉類的特性

Java枚舉類的特性有:

枚舉可以實現接口,但不能繼承接口,也不能被繼承。枚舉類是final的,所以不能繼承。枚舉類的構造方法是私有的枚舉成員是靜態、final和public枚舉成員是枚舉類的實例但是從上面SeasonEnum枚舉類的定義來看,完全看不出這些特性,這些特性是怎麼來的呢? 請看下面的原理探求。

Java枚舉類實現的原理探求

ava枚舉類型的奧秘就在編譯階段,枚舉類在編譯後會生成了一個擴展java.lang.Enum的類。這個可以通過JDK自帶的javap工具來反編譯生成的.class文件。對上面的生成的SeasonEnum.class文件進行反編譯,因為這個文件的包路徑是cn\osxm\jcodef\func\base,所以在命令行使用如下命令:

javap -p cn\osxm\jcodef\func\base\SeasonEnum.class

-p參數的意思是反編譯代碼中包含私有的方法, p是private的意思。從控制臺輸出的反編譯後的源碼可以看出:

自定義的枚舉類會自動繼承java.lang.Enum類每個成員變量都會被轉換為 private static final的枚舉類型的實例自動添加private的構造函數 從反編譯後的源碼就不難理解Enum的特性了。注意: 使用專門的Java反編譯工具,比如JD GUI、luyten等對Eumn進行反編譯的效果接近源碼的效果,無法看到繼承等特性,JD-GUI反編譯的效果和源碼時一致的,這也說明使用JD GUI來進行實際的反編譯還是不錯的。

相關焦點

  • java enum(枚舉)使用詳解 + 總結
    enum 的全稱為 enumeration, 是 JDK 1.5 中引入的新特性,存放在 java.lang 包中。下面是我在使用 enum 過程中的一些經驗和總結。enum 關鍵字,隱含了所創建的類型都是 java.lang.Enum 類的子類(java.lang.Enum 是一個抽象類)。
  • Java面向對象之枚舉——enum
    Java面向對象之枚舉——enum引出枚舉首先來考慮這樣一個需求:判斷一個員工(Employee)在一周的哪一天休息。枚舉語法在上述案例中的WeekDay類用枚舉來重寫就是這樣的:enum WeekDay {MONDAY,TUESDAY
  • Java 枚舉類型使用,枚舉集合介紹
    枚舉類型從前面的數據類型章節可知 Java 中並沒有枚舉類型,但通過 Java API 中的 java.lang.Enum 枚舉類我們可以定義枚舉類型數據,本質上還是一個類類型。有時後變量只會取幾個確定值中的一個,這時枚舉類型就很方便了,如定義一周的星期幾:1.枚舉類型的定義通過關鍵字 enum 定義枚舉類型數據,數據值一般採用大寫。定義位置可以放在類中,類的外部,或者另外的文件中定義。
  • C語言中的enum(枚舉)用法
    ; "|" << test <<endl; cout="" pre="" return="" test="(enum"><pre class="brush:java;">看到這裡要最後說一個問題,就是枚舉變量中的枚舉元素(或者叫枚舉常量)在特殊情況下是會被自動提升為算術類型的!
  • Java enum的用法詳解
    現在好了,有了枚舉,可以把相關的常量分組到一個枚舉類型裡,而且枚舉提供了比常量更多的方法。public enum Color { RED, GREEN, BLANK, YELLOW }用法二:switchJDK1.6之前的switch語句只支持int,char,enum類型,使用枚舉,能讓我們的代碼可讀性更強。
  • c語言之枚舉類型(enum)
    如果一個變量只有幾種可能的值,則可以定義為「枚舉類型」;所謂「枚舉」就是把可能的值一一的列舉出來,變量的值只限於列舉出來的值的範圍, 如: 語法: enum 枚舉類型{枚舉成員列表}; //其中的枚舉成員列表是以逗號「,」相分隔 如:    enum Spectrum{red,balck,yellow,blue,white};時間:2018
  • C語言經典語法-枚舉類型enum用法
    ,因為枚舉成員的是常量,所以不能對它們賦值,只能將它們的值賦給其他的變量 枚舉類型(枚舉標籤)、枚舉成員(枚舉常量)、枚舉變量之間的區別當枚舉類型和枚舉變量放在一起定義時,枚舉類型的名字(就是enum week中的week)可以省略不寫,意思是上圖的有兩種寫法第一種:enum week{Mon = 1, Tues, Wed, Thurs}num
  • Java枚舉用法詳解
    概念enum 的全稱為 enumeration, 是 JDK 1.5 中引入的新特性。在Java中,被 enum 關鍵字修飾的類型就是枚舉類型。形式如下:enum Color { RED, GREEN, BLUE }如果枚舉不添加任何方法,枚舉值默認為從0開始的有序數值。
  • 詳細講解C語言enum枚舉類型
    在 C 語言中對這樣取值比較特殊的變量可以定義為枚舉類型。所謂枚舉是指將變量的值一一列舉出來,變量只限於列舉出來的值的範圍內取值。 定義一個變量是枚舉類型,可以先定義一個枚舉類型名,然後再說明這個變量是該枚舉類型。
  • 新手入門:C/C++中枚舉類型(enum)
    如果一個變量你需要幾種可能存在的值,那麼就可以被定義成為枚舉類型。之所以叫枚舉就是說將變量或者叫對象可能存在的情況也可以說是可能的值一一例舉出來。   舉個例子來說明一吧,為了讓大家更明白一點,比如一個鉛筆盒中有一支筆,但在沒有打開之前你並不知道它是什麼筆,可能是鉛筆也可能是鋼筆,這裡有兩種可能,那麼你就可以定義一個枚舉類型來表示它!
  • Java枚舉使用詳解
    在java中如何更好的使用這些「數據集」呢?因此枚舉便派上了用場,以下代碼詳細介紹了枚舉的用法。package com.ljq.test; /** * 枚舉用法詳解 * * @author jiqinlin * */ public class TestEnum { /** * 普通枚舉 * * @author jiqinlin * */ public enum ColorEnum { red, green, yellow, blue; } /** * 枚舉像普通的類一樣可以添加屬性和方法
  • C語言中的enum(枚舉)
    枚舉語法定義格式為:enum 枚舉名 {枚舉元素1,枚舉元素2,……};    接下來我們舉個例子,比如:一星期有 7 天,如果不用枚舉,我們需要使用 #define 來為每個整數定義一個別名:    這個看起來代碼量就比較多,接下來我們看看使用枚舉的方式:enum DAY{      MON=1, TUE
  • 一文搞懂 Java 中的枚舉,寫得非常好!
    枚舉的典型應用場景:錯誤碼、狀態機等。枚舉類型的本質儘管 enum看起來像是一種新的數據類型,事實上,enum是一種受限制的類,並且具有自己的方法。創建enum時,編譯器會為你生成一個相關的類,這個類繼承自 java.lang.Enum。
  • 【枚舉】用好 Java 中的枚舉,真的沒有那麼簡單!
    這篇文章由 JavaGuide 翻譯,公眾號: JavaGuide,原文地址:https://www.baeldung.com/a-guide-to-java-enums 。轉載請註明上面這段文字。」1.概覽在本文中,我們將看到什麼是 Java 枚舉,它們解決了哪些問題以及如何在實踐中使用  Java 枚舉實現一些設計模式。enum關鍵字在 java5 中引入,表示一種特殊類型的類,其總是繼承java.lang.Enum類,更多內容可以自行查看其官方文檔。
  • 每日一課 | Java –比較枚舉值
    Java枚舉示例Language.javapackage com.mkyong.java public enum Language {    JAVA,    PYTHON,    NODE,    NET,    RUBY}2.與==比較將枚舉值與==運算符進行比較的示例。
  • 【C語言資料更新】C語言中的枚舉類型(enum)
    enum 枚舉名{  標識符[=整型常數],    標識符[=整型常數],    ...  標識符[=整型常數]} 枚舉變量;當然,我們也可以使用typedef關鍵詞,將一個枚舉定義成一種模板數據類型,其形式為:typedef enum{  標識符[=整型常數],  標識符[=整型常數],  ...
  • Java枚舉深度解讀,看這篇就夠了
    ,但是就像上面說到的,如果開發中枚舉類型較多,開發多個這樣的自定義枚舉類會非常的耗時,所以 jdk 5.0 之後,推出了 Enum 關鍵字定義枚舉類(三)Enum 關鍵字定義枚舉類(jdk 5.0之後)enum 全稱為 enumeration,是jdk 5.0 中引入的新特性,在Java 中被 enum 關鍵字修飾的類型就是枚舉類型
  • Java基礎,基礎類型包裝類、Math類、枚舉簡介
    一、基礎類型包裝類;之前講解了基礎類型,現在又來一個基礎類型包裝類,那這個基礎類型包裝類是什麼意思呢?基礎類型包括六種數字類型(4個整數類型,2個浮點型),一種字符型,一種boolean型,每種基礎類型都對應的有包裝類,包裝類就是可以將基礎類型包裝成一個對象的類,所以是基礎類型包裝類,對應關係見下圖;基礎包裝類有什麼用法呢?
  • 程序進階:一起來用用Java枚舉
    比如當我們需要對一些類的屬性需要作出限制時,這些方法就不太適用,為了解決這種問題,在JDK1.5之後引入了枚舉類型,這篇文章中老梁就和大家一起好好聊聊枚舉。還是老樣子,老梁還是先舉一個例子來闡述枚舉的基本定義,如下圖:從老梁上面的例子大家可以看出枚舉的特點,那就是枚舉在使用的時候有點像Java中對象的常量定義,不過在枚舉的定義中對這些常量進行了確切的定義,不可以隨意更改。對於「常量」的使用來說,我們通常的使用就是需要將它進行遍歷。
  • Java中枚舉的線程安全性及序列化問題
    Java SE5提供了一種新的類型-Java的枚舉類型,關鍵字enum可以將一組具名的值的有限集合創建為一種新的類型,而這些具名的值可以作為常規的程序組件使用,這是一種非常有用的功能。本文將深入分析枚舉的源碼,看一看枚舉是怎麼實現的,他是如何保證線程安全的,以及為什麼用枚舉實現的單例是最好的方式。要想看源碼,首先得有一個類吧,那麼枚舉類型到底是什麼類呢?是enum嗎?