一、什么是枚舉類型
????????枚舉類型是一種特殊的數據類型,用于定義一組固定的命名常量。枚舉類型提供了一種更強大、更安全和更易讀的方式來表示一組相關的常量。
????????在Java中,枚舉類型是通過使用enum關鍵字來定義的。枚舉類型可以包含一個或多個枚舉常量,每個常量都是枚舉類型的實例。枚舉常量是在枚舉類型中預先定義的,它們是唯一的、已命名的對象。
????????在Java中,枚舉類型是一組固定常量值的集合,每個常量值代表一個特定的數據類型。枚舉在Java中被視為數據類型,你可以使用它們來創建枚舉類型的變量、數組、參數等。
二、枚舉的引入
要求創建一個季節(Season)類,只能創建春夏秋冬4個對象。
- 舊方法:假如按照以往的思路,只能創建一個普通的Season 類。
- 代碼如下:
public class Enumeration01 {public static void main(String[] args) {//使用Season spring = new Season("春天", "溫暖");Season winter = new Season("冬天", "寒冷");Season summer = new Season("夏天", "炎熱");Season autumn = new Season("秋天", "涼爽");Season other = new Season("紅天", "~~~");// 可以隨意多創建對象,不滿足題目要求
// autumn.setName("XXX");// 會改變對象的屬性,不滿足題目的要求
// autumn.setDesc("非常的熱..");}
}
class Season{//類private String name;private String desc;// 季節描述public Season(String name, String desc) {this.name = name;this.desc = desc;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}
}
????????思考:使用普通類的定義,我們不能體現Season 類只有4個固定的對象,因為使用者可以隨意創建更多的對象。因此我們需要一種特殊的類,可以限制使用者創建的對象的個數與類型 ---- 于是便引入了枚舉類。
????????枚舉(enumeration):枚舉是一組常量的集合;它是一種特殊的類,里面只包含一組有限的特殊的不能修改的對象。
三、枚舉的基本用法
- 使用 enum 關鍵字實現枚舉:
使用步驟:
(1)使用 enum 關鍵字取代 class 關鍵字定義一個類,該類便稱為枚舉類。
(2)在枚舉類內部直接創建對象,枚舉類對象是默認使用 public static final 一起修飾的,如果有多個對象,則必須且只能使用(,)間隔開。
(3)在枚舉類中將構造器私有化,防止外部隨意創建枚舉類對象。
(4)只保留屬性的get 方法,不提供屬性的 set 方法,防止枚舉類的對象屬性被更改。
- 將上例代碼修改如下:
public class Enumeration03 {public static void main(String[] args) {System.out.println(Season.AUTUMN);System.out.println(Season.SUMMER);}
}enum Season {//類//定義了四個靜態對象,使用了enum 來實現枚舉類/*1. 使用關鍵字 enum 替代 class;2. public static final Season SPRING = new Season("春天", "溫暖") 直接使用SPRING("春天", "溫暖") 來代替,即常量名(實參列表);3. 如果有多個常量(對象), 使用 , 號間隔即可;4. 如果使用enum 來實現枚舉,要求將定義常量對象的語句,寫在第一行;5. 如果我們使用的是無參構造器,創建常量對象,則可以省略括號();*/SPRING("春天", "溫暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "涼爽"),SUMMER("夏天", "炎熱");// 調用了構造器// 下面定義對象的語句和上面的效果是一樣的。
// public static final Season SPRING = new Season("春天", "溫暖");
// public static final Season WINTER = new Season("冬天", "寒冷");
// public static final Season AUTUMN = new Season("秋天", "涼爽");
// public static final Season SUMMER = new Season("夏天", "炎熱");private String name;private String desc;private Season() {//無參構造器}private Season(String name, String desc) {this.name = name;this.desc = desc;}public String getName() {return name;}public String getDesc() {return desc;}// 打印對象的信息@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}
- 說明:使用 enum 關鍵字后,Season 類中的對象變成了固定的對象,這樣便能滿足我們一開始提出的要求了。
- 對比圖如下:
四、枚舉的注意事項和細節?
(1)當我們使用 enum 關鍵字開發一個枚舉類時,默認會繼承 Enum 類,而且是一個 final 類,不能再被其他類繼承。
(2)傳統的 public static final Season2 SPRING = new Season2(“春天”, “溫暖”); 簡化成 SPRING(“春天”, “溫暖”), 這里必 須知道,它調用的是哪個構造器。
(3)如果使用無參構造器 創建 枚舉對象時,其實參列表和小括號都可以省略。
(4)當有多個枚舉對象時,使用(,)間隔,最后由一個分號結尾。
(5)定義類枚舉對象的語句必須放在枚舉類的第一句。(6)使用 enum 關鍵字后,就不能再繼承其它類了,因為 enum 類會隱式繼承 Enum,而 Java 是單繼承機制。
五、枚舉類的常用方法
以下是枚舉類型常用的方法以及它們的用途:
- 代碼演示:
public class EnumMethod {public static void main(String[] args) {//使用Season 枚舉類,來演示各種方法Season autumn = Season.AUTUMN;//輸出枚舉對象的名字 AUTUMNSystem.out.println(autumn.name());//ordinal() 輸出的是該枚舉對象的次序/位置號,從0開始編號//AUTUMN 枚舉對象是第三個,因此輸出 2System.out.println(autumn.ordinal());// values方法,返回 Season2[]// 含有定義的所有枚舉對象Season[] values = Season.values();System.out.println("===遍歷取出枚舉對象(增強for)====");for (Season season: values) {System.out.println(season);}//valueOf:將字符串轉換成枚舉對象,要求字符串必為已有的對象名,否則報異常//執行流程//1. 根據你輸入的 "AUTUMN" 到 Season2的枚舉對象去查找//2. 如果找到了,就返回,如果沒有找到,就報錯Season autumn1 = Season.valueOf("AUTUMN");System.out.println("autumn1=" + autumn1);System.out.println(autumn == autumn1);//compareTo:比較兩個枚舉常量,比較的就是位置號// 就是把 Season.AUTUMN 枚舉對象的位置號 和 Season.SUMMER枚舉對象的位置號比較/*源碼如下:public final int compareTo(E o) {return self.ordinal - other.ordinal;}*/// Season.AUTUMN的編號[2] - Season.SUMMER的編號[3]System.out.println(Season.AUTUMN.compareTo(Season.SUMMER));// 最后補充了一個增強forint[] nums = {1, 2, 9};//普通的for循環System.out.println("=====普通的for=====");for (int i = 0; i < nums.length; i++) {System.out.println(nums[i]);}System.out.println("=====增強的for=====");//執行流程是 依次從nums數組中取出數據,賦給i, 如果取出完畢,則退出forfor(int i : nums) {System.out.println("i=" + i);}}
}
六、枚舉的優缺點
優點:
1.易讀性和可維護性:枚舉類型中的常量是有意義的、自描述的,使得代碼更易讀、易理解和易于維護。枚舉常量具有唯一的名稱,提供了更好的文檔和注釋。
2.類型安全:枚舉類型在編譯時進行靜態類型檢查,這意味著編譯器可以確保只使用有效的枚舉常量,提供了更高的類型安全性。
3.可限定的值集合:枚舉類型定義了一個有限的值集合,限定了有效的取值范圍。這可以幫助避免程序中出現無效或意外的取值。
4.避免魔法數值:使用枚舉類型可以避免使用硬編碼的魔法數值,提供了更好的代碼可讀性和可維護性。
5.增強的編譯器支持:枚舉類型在編譯器層面提供了一些額外的支持,如自動添加常用方法(如values()、valueOf())、枚舉常量的順序等。
6.適用于狀態和選項的表示:枚舉類型非常適用于表示狀態、選項和固定集合,如季節、顏色、星期幾等。
?
缺點:
1.不適用于動態變化的數據:枚舉類型是在編譯時定義的,其常量集合是固定的。如果需要表示動態變化的數據集合,枚舉類型可能不適合。
2.不適用于大型數據集合:如果需要表示大型的數據集合,枚舉類型的常量定義可能會變得冗長和繁瑣。
3.缺乏擴展性:枚舉類型的常量是在編譯時確定的,不支持動態添加或刪除常量。因此,如果需要頻繁地修改常量集合,可能會導致代碼的改動和維護成本的增加。
4.不支持繼承:枚舉類型不支持繼承,無法實現枚舉類型之間的繼承關系。
?