Java的枚舉類型使用方法詳解
1.背景
在java語言中還沒有引入枚舉類型之前,表示枚舉類型的常用模式是聲明一組具有int常量。之前我們通常利用public final static 方法定義的代碼如下,分別用1 表示春天,2表示夏天,3表示秋天,4表示冬天。
public class Season {
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
}
這種方法稱作int枚舉模式。可這種模式有什么問題呢,我們都用了那么久了,應(yīng)該沒問題的。通常我們寫出來的代碼都會考慮它的安全性、易用性和可讀性。 首先我們來考慮一下它的類型安全性。當(dāng)然這種模式不是類型安全的。比如說我們設(shè)計一個函數(shù),要求傳入春夏秋冬的某個值。但是使用int類型,我們無法保證傳入的值為合法。代碼如下所示:
private String getChineseSeason(int season){
StringBuffer result = new StringBuffer();
switch(season){
case Season.SPRING :
result.append("春天");
break;
case Season.SUMMER :
result.append("夏天");
break;
case Season.AUTUMN :
result.append("秋天");
break;
case Season.WINTER :
result.append("冬天");
break;
default :
result.append("地球沒有的季節(jié)");
break;
}
return result.toString();
}
public void doSomething(){
System.out.println(this.getChineseSeason(Season.SPRING));//這是正常的場景
System.out.println(this.getChineseSeason(5));//這個卻是不正常的場景,這就導(dǎo)致了類型不安全問題
}
程序getChineseSeason(Season.SPRING)是我們預(yù)期的使用方法??蒰etChineseSeason(5)顯然就不是了,而且編譯很通過,在運行時會出現(xiàn)什么情況,我們就不得而知了。這顯然就不符合Java程序的類型安全。
接下來我們來考慮一下這種模式的可讀性。使用枚舉的大多數(shù)場合,我都需要方便得到枚舉類型的字符串表達(dá)式。如果將int枚舉常量打印出來,我們所見到的就是一組數(shù)字,這是沒什么太大的用處。我們可能會想到使用String常量代替int常量。雖然它為這些常量提供了可打印的字符串,但是它會導(dǎo)致性能問題,因為它依賴于字符串的比較操作,所以這種模式也是我們不期望的。 從類型安全性和程序可讀性兩方面考慮,int和String枚舉模式的缺點就顯露出來了。幸運的是,從Java1.5發(fā)行版本開始,就提出了另一種可以替代的解決方案,可以避免int和String枚舉模式的缺點,并提供了許多額外的好處。那就是枚舉類型(enum type)。接下來的章節(jié)將介紹枚舉類型的定義、特征、應(yīng)用場景和優(yōu)缺點。
2.定義
枚舉類型(enum type)是指由一組固定的常量組成合法的類型。Java中由關(guān)鍵字enum來定義一個枚舉類型。下面就是java枚舉類型的定義。
public enum Season {
SPRING, SUMMER, AUTUMN, WINER;
}
3.特點
Java定義枚舉類型的語句很簡約。它有以下特點:
1) 使用關(guān)鍵字enum 2) 類型名稱,比如這里的Season 3) 一串允許的值,比如上面定義的春夏秋冬四季 4) 枚舉可以單獨定義在一個文件中,也可以嵌在其它Java類中。
除了這樣的基本要求外,用戶還有一些其他選擇
5) 枚舉可以實現(xiàn)一個或多個接口(Interface) 6) 可以定義新的變量 7) 可以定義新的方法 8) 可以定義根據(jù)具體枚舉值而相異的類
4.應(yīng)用場景
以在背景中提到的類型安全為例,用枚舉類型重寫那段代碼。代碼如下:
public enum Season {
SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);
private int code;
private Season(int code){
this.code = code;
}
public int getCode(){
return code;
}
}
public class UseSeason {
/**
* 將英文的季節(jié)轉(zhuǎn)換成中文季節(jié)
* @param season
* @return
*/
public String getChineseSeason(Season season){
StringBuffer result = new StringBuffer();
switch(season){
case SPRING :
result.append("[中文:春天,枚舉常量:" + season.name() + ",數(shù)據(jù):" + season.getCode() + "]");
break;
case AUTUMN :
result.append("[中文:秋天,枚舉常量:" + season.name() + ",數(shù)據(jù):" + season.getCode() + "]");
break;
case SUMMER :
result.append("[中文:夏天,枚舉常量:" + season.name() + ",數(shù)據(jù):" + season.getCode() + "]");
break;
case WINTER :
result.append("[中文:冬天,枚舉常量:" + season.name() + ",數(shù)據(jù):" + season.getCode() + "]");
break;
default :
result.append("地球沒有的季節(jié) " + season.name());
break;
}
return result.toString();
}
public void doSomething(){
for(Season s : Season.values()){
System.out.println(getChineseSeason(s));//這是正常的場景
}
//System.out.println(getChineseSeason(5));
//此處已經(jīng)是編譯不通過了,這就保證了類型安全
}
public static void main(String[] arg){
UseSeason useSeason = new UseSeason();
useSeason.doSomething();
}
}
[中文:春天,枚舉常量:SPRING,數(shù)據(jù):1] [中文:夏天,枚舉常量:SUMMER,數(shù)據(jù):2] [中文:秋天,枚舉常量:AUTUMN,數(shù)據(jù):3] [中文:冬天,枚舉常量:WINTER,數(shù)據(jù):4]
這里有一個問題,為什么我要將域添加到枚舉類型中呢?目的是想將數(shù)據(jù)與它的常量關(guān)聯(lián)起來。如1代表春天,2代表夏天。
5.總結(jié)
那么什么時候應(yīng)該使用枚舉呢?每當(dāng)需要一組固定的常量的時候,如一周的天數(shù)、一年四季等?;蛘呤窃谖覀兙幾g前就知道其包含的所有值的集合。Java 1.5的枚舉能滿足絕大部分程序員的要求的,它的簡明,易用的特點是很突出的。
6.用法
用法一:常量
public enum Color {
RED, GREEN, BLANK, YELLOW
}
用法二:switch
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
用法三:向枚舉中添加新方法
public enum Color {
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變量
private String name;
private int index;
// 構(gòu)造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
用法四:覆蓋枚舉的方法
public enum Color {
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變量
private String name;
private int index;
// 構(gòu)造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//覆蓋方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}
用法五:實現(xiàn)接口
public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變量
private String name;
private int index;
// 構(gòu)造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
用法六:使用接口組織枚舉
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
Java運行時環(huán)境之ClassLoader類加載機(jī)制詳解
這篇文章主要給大家介紹了關(guān)于Java運行時環(huán)境之ClassLoader類加載機(jī)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
javaweb前端向后端傳值的幾種方式總結(jié)(附代碼)
javaweb是java開發(fā)中的一個方向,下面這篇文章主要給大家介紹了關(guān)于javaweb前端向后端傳值的幾種方式的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
Java Grpc實例創(chuàng)建負(fù)載均衡詳解
這篇文章主要介紹了Java Grpc實例創(chuàng)建負(fù)載均衡詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
詳解Java中ExceptionInInitializer錯誤的解決方法
ExceptionInInitializerError 是 Java 中的未經(jīng)檢查的異常,它是 Error 類的子類, 它屬于運行時異常的類別,下面我們就來看看它的具體解決方法吧2024-02-02
教你使用springSecurity+jwt實現(xiàn)互踢功能
JWT作為一個開放的標(biāo)準(zhǔn)( RFC 7519 ),定義了一種簡潔的,自包含的方法用于通信雙方之間以Json對象的形式安全的傳遞信息。接下來通過本文給大家介紹springSecurity+jwt實現(xiàn)互踢功能,需要的朋友可以參考下2021-11-11
Java基礎(chǔ)教程之對象的方法與數(shù)據(jù)成員
這篇文章主要介紹了Java基礎(chǔ)教程之對象的方法與數(shù)據(jù)成員,本文講解對象的方法與數(shù)據(jù)成員相關(guān)知識,因為java是面向?qū)ο笳Z言,本文的知識都是經(jīng)常要用到的,需要的朋友可以參考下2014-08-08

