Java enum枚舉在實際項目中的常用方法


在項目實際開發過程中,經常會遇到對某些固定的值、字典項的定義的需求,很多項目經常使用常量來定義,其實在jdk1.5就已經引入了枚舉,使用枚舉可以更好的解決這類需求,本文主要記錄枚舉的優勢以及經常在項目中使用的方法。

知識點

  • 枚舉類命名
    枚舉類的命名通常需要Enum為后綴,枚舉成員名稱需要全大寫,單詞間用下划線隔開。
  • 枚舉類不允許使用 extends 關鍵字
    枚舉類默認會繼承java.lang.Enum,由於java是單繼承,所以在定義枚舉類時不允許再繼承其他類,但可以實現多個接口
  • 枚舉的比較可以直接使用 ==
    枚舉是不允許被new出來的,枚舉類里的構造函數都限定為私有化,是不允許使用public定義構造函數的。枚舉的賦值,如果是同一個元素,則會指向同一個地址,所以是可以直接使用==的,當然在Enum類中,重寫了equals方法(如下圖),所以也是可以用equals來判斷。
    在這里插入圖片描述
  • 枚舉常用方法
方法名 用途
name() 返回枚舉常量名
toString() 返回枚舉常量名
values() 返回枚舉成員數組
valueOf() 通過枚舉常量名返回枚舉
ordinal() 返回枚舉常量在enum聲明中的位置,位置是從0開始計數的
  • 枚舉在switch中的使用
    枚舉在switch中的使用,優勢在於能控制case的范圍(看以下實例),並且在idea中有相關提示
  • 枚舉在單例模式的使用
    首先使用枚舉類實現單例模式,寫法相當簡單,看最后的實例;其次枚舉是線程安全、單一實例(由於構造方法都是私有的,不能被new)

實例

1. 最簡單的枚舉

在項目中經常會遇到一些固定值的定義,以往都是用常量來定義,以下用實例說明,為啥枚舉的方式優於常量的方式,以下就以季節的定義為例

1.1 使用常量來實現

/**
 * @Description: 季節常量定義
 */
public class SeasonConst {
    /**
     * 春季
     */
    public static final String SPRING = "SPRING";
    /**
     * 夏季
     */
    public static final String SUMMER = "SUMMER";
    /**
     * 秋季
     */
    public static final String AUTUMN = "AUTUMN";
    /**
     * 冬季
     */
    public static final String WINTER = "WINTER";
}

以上實例雖然實現了功能,但有兩點比較明顯的缺點:

  1. 常量值容易寫錯(特別是復制黏貼,但是忘記改對應的值,導致系統出bug),idea不會給任何提示。
    比如,某人粗心,在復制黏貼代碼時變成(將春季、夏季都定義成春季了):
/**
 * 春季
 */
public static final String SPRING = "SPRING";
/**
 * 夏季
 */
public static final String SUMMER = "SPRING";
  1. 如果我想知道一年總共多少個季節,咋整?用常量定義的類,有點捉襟見肘

1.2 使用枚舉來實現,可以實現常量的所有功能,並能輕松解決以上提出的常量的兩個缺點

  • 定義枚舉類SeasonEnum
public enum SeasonEnum {
    /**
     * 春季
     */
    SPRING,
    /**
     * 夏季
     */
    SUMMER,
    /**
     * 秋季
     */
    AUTUMN,
    /**
     * 冬季
     */
    WINTER
}

在SeasonEnum枚舉類中,如果定義兩個 SPRING,編譯器會直接報錯,很好解決了常量的第一個缺點

  • 該枚舉類的使用(1、獲取枚舉值的名稱;2、枚舉判斷的使用;3、枚舉循環的使用。通過枚舉的循環,很好解決了常量的第二個缺點;)
//獲取枚舉值的名稱,與toString得到的結果一樣
String spring = SeasonEnum.SPRING.name();
System.out.println(spring);

//枚舉判斷的使用
SeasonEnum springEnum1 = SeasonEnum.SPRING;
SeasonEnum springEnum2 = SeasonEnum.SPRING;
SeasonEnum summerEnum3 = SeasonEnum.SUMMER;
//由於springEnum1、springEnum2都指向SPRING,所以輸出true
System.out.println("springEnum1 == springEnum2:" + (springEnum1 == springEnum2));
//由於springEnum1指向SPRING、summerEnum3指向SUMMER,所以輸出false
System.out.println("springEnum1 == summerEnum3:" + (springEnum1 == summerEnum3));

//循環枚舉,打印枚舉類中的所有枚舉成員
SeasonEnum[] seasonEnums = SeasonEnum.values();
for (SeasonEnum seasonEnum : seasonEnums) {
    System.out.println(seasonEnum.name());
}
  • 枚舉在switch中的使用,如果case后跟不存在SeasonEnum類中的枚舉(比如 case OTHER),則編譯器會報錯
String enumName = "SPRING";
SeasonEnum seasonEnum = SeasonEnum.valueOf(enumName);
switch (seasonEnum){
    case SPRING:
       System.out.println(seasonEnum.name());
       break;
    case SUMMER:
        System.out.println(seasonEnum.name());
        break;
    case AUTUMN:
        System.out.println(seasonEnum.name());
        break;
    case WINTER:
        System.out.println(seasonEnum.name());
        break;
    default:
        System.out.println("other");
}

2.在枚舉中使用自定義屬性和方法

項目中經常也會遇到一些字典項的定義,比如性別,包含存入數據庫中的值,以及顯示在頁面上的值。以下通過實例來實現性別字典。

  • 定義SexEnum(注意看代碼中的注解)
public enum SexEnum {
    MAN("man","男"),
    WOMEN("women","女");

    private String sexCode;

    private String sexName;

    /**
     * 自定義構造函數,以完成枚舉對sexCode、sexName賦值
     * @param sexCode
     * @param sexName
     */
    SexEnum(String sexCode,String sexName){
        this.sexCode = sexCode;
        this.sexName = sexName;
    }

    /**
     * 獲取sexCode
     * @return
     */
    public String getSexCode() {
        return sexCode;
    }

    /**
     * 獲取sexName
     * @return
     */
    public String getSexName() {
        return sexName;
    }

    /**
     * 項目中經常會根據code,轉換成對應的name
     * 所以這里自定義方法,根據sexCode獲取sexName
     * 通過循環enum來實現
     * @param sexCode
     * @return
     */
    public static String getSexNameByCode(String sexCode){
        String sexName = "sexCode不存在";
        SexEnum[] sexEnums = SexEnum.values();
        for (SexEnum sexEnum : sexEnums) {
            if(sexEnum.getSexCode().equals(sexCode)){
                sexName =  sexEnum.getSexName();
                break;
            }
        }
        return sexName;
    }

    /**
     * 項目中也有根據name,轉換成對應的code
     * 所以這里自定義方法,根據sexName獲取sexCode
     * 通過循環enum來實現
     * @param sexName
     * @return
     */
    public static String getSexCodeByName(String sexName){
        String sexCode = "sexName不存在";
        SexEnum[] sexEnums = SexEnum.values();
        for (SexEnum sexEnum : sexEnums) {
            if(sexEnum.getSexName().equals(sexName)){
                sexCode =  sexEnum.getSexCode();
                break;
            }
        }
        return sexCode;
    }

    /**
     * 根據sexCode獲取SexEnum,在switch中使用
     * 通過循環enum來實現
     * @param sexCode
     * @return
     */
    public static SexEnum getEnumByCode(String sexCode){
        SexEnum[] sexEnums = SexEnum.values();
        for (SexEnum sexEnum : sexEnums) {
            if(sexEnum.getSexCode().equals(sexCode)){
                return sexEnum;
            }
        }
        return null;
    }

    /**
     * 重寫toString方法
     * @return
     */
    @Override
    public String toString() {
        return this.sexCode + ":" + this.sexName;
    }
}
  • SexEnum枚舉類的使用
public class EnumMain {

    public static void main(String[] args){
        //循環帶自定義方法的枚舉
        SexEnum[] sexEnums = SexEnum.values();
        for (SexEnum sexEnum : sexEnums) {
            System.out.println("sexCode:"+sexEnum.getSexCode());
            System.out.println("sexName:"+sexEnum.getSexName());
            System.out.println("sexCode:sexName="+sexEnum.toString());
        }

        //根據sexCode獲取sexName
        String sexName = SexEnum.getSexNameByCode("women");
        System.out.println("根據sexCode獲取sexName:" + sexName);

        //根據sexName獲取sexCode
        String sexCode = SexEnum.getSexCodeByName("男");
        System.out.println("根據sexName獲取sexCode:" + sexCode);

        //通過傳入的sexCode使用switch
        testSexEnumSwitch("women");

    }
    /**
     * 實際項目中,基本上都是傳sexCode的,所以這里也根據傳入的sexCode,使用switch方法
     * @param sexCode
     */
    private static void testSexEnumSwitch(String sexCode){
        //自定義getEnumByCode方法,通過sexCode獲取SexEnum
        SexEnum sexEnum = SexEnum.getEnumByCode(sexCode);
        switch (sexEnum){
            case MAN:
                System.out.println(sexEnum.toString());
                break;
            case WOMEN:
                System.out.println(sexEnum.toString());
                break;
            default:
                System.out.println("other");
        }
    }
}

3.通過枚舉實現單例

  • 單例定義
public enum Singleton {
    INSTALL;
    /**
     * 自定義方法
     */
    public void yourMethod(){
        System.out.println("do your business");
    }
}
  • 調用方法
Singleton.INSTALL.yourMethod();

源碼獲取

以上示例都可以通過我的GitHub獲取完整的代碼,點擊獲取


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM