天天看點

枚舉代替常量

1、簡介

不知道大家有沒有在自己項目中看到過類似下面這樣的代碼:

public static void fruitsHandle(String fruits) {

    switch (fruits) {

        case "Apple":

            // TODO

            break;

        case "Banana":

        case "Orange":

        default:

            throw new IllegalStateException("Unexpected value: " + fruits);

    }

}

出現上面這種情況是非常少的,小萌新一般也不會直接在方法中重複定義字元串進行比較,而會将其定義為常量,或者統一抽取為常量類。是以一般會看到這種代碼(小捌經常在項目中看到類似這樣的代碼,但是小捌不敢吭聲😄😄):

private static final String APPLE = "Apple";

private static final String BANANA = "Banana";

private static final String ORANGE = "Orange";

        case APPLE:

        case BANANA:

        case ORANGE:

上面這種情況我們在代碼中出現的頻率非常高;它需要程式員提供一組固定常量,并且這一組固定常量在開發時或者說編譯時就知道了具體的成員,這個時候我們就應該使用枚舉。

枚舉類型(enum type)是指由一組固定常量組成合法值的類型。

2、優勢

使用枚舉類型,相比直接定義常量能夠帶來非常多的好處。

2.1 類型安全

分别定義一個簡單的肉類枚舉和水果枚舉

// 肉類枚舉

public enum MeetEnums {

    BEEF,

    PORK,

    FISH;

// 水果枚舉

public enum FruitsEnums {

    APPLE,

    BANANA,

    ORANGE;

我們改造上面的代碼,修改入參類型即可

public static void fruitsHandle(FruitsEnums fruits) {

可以看到定義枚舉類型帶來函數類型安全性,如果定義的是常量則無法代理這種效果

枚舉代替常量

2.2 枚舉能夠提供更多資訊

枚舉在本質上還是一個類,它能夠定義屬性和方法,我們可以在枚舉類中定義想要的方法、或者通過屬性擴充枚舉提供的基礎資訊。

比如我們做web開發時最常見的HttpStatus,在springframework架構中就被定義成了枚舉類,它不僅包含了Http響應碼,還能包含描述狀态。

public enum HttpStatus {

 OK(200, "OK"),

    NOT_FOUND(404, "Not Found"),

    INTERNAL_SERVER_ERROR(500, "Internal Server Error");

    private final int value;

    private final String reasonPhrase;

    private HttpStatus(int value, String reasonPhrase) {

        this.value = value;

        this.reasonPhrase = reasonPhrase;

2.3 通過函數提供更多服務

此外HttpStatus它内部還嵌套了Series枚舉類,這個類可以協助HttpStatus枚舉類,通過statusCode / 100的模判斷目前的枚舉狀态是is1xxInformational、is2xxSuccessful、is3xxRedirection、is4xxClientError、is5xxServerError等等。

public static enum Series {

        INFORMATIONAL(1),

        SUCCESSFUL(2),

        REDIRECTION(3),

        CLIENT_ERROR(4),

        SERVER_ERROR(5);

        private final int value;

        private Series(int value) {

            this.value = value;

        }

        public int value() {

            return this.value;

        public static HttpStatus.Series valueOf(HttpStatus status) {

            return valueOf(status.value);

        public static HttpStatus.Series valueOf(int statusCode) {

            HttpStatus.Series series = resolve(statusCode);

            if (series == null) {

                throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");

            } else {

                return series;

            }

        @Nullable

        public static HttpStatus.Series resolve(int statusCode) {

            int seriesCode = statusCode / 100;

            HttpStatus.Series[] var2 = values();

            int var3 = var2.length;

            for(int var4 = 0; var4 < var3; ++var4) {

                HttpStatus.Series series = var2[var4];

                if (series.value == seriesCode) {

                    return series;

                }

            return null;

2.4 擷取所有定義的類型

所有的枚舉類會自動産生一個values()方法,它能傳回目前定義枚舉類的數組集,是以可以很友善的周遊怎麼枚舉類定義的所有枚舉。比如我們簡單改造一下MeetEnums枚舉類:

    BEEF("牛肉"),

    PORK("豬肉"),

    FISH("魚肉");

    String name;

    public String getName() {

        return name;

    MeetEnums(String name) {

        this.name = name;

    public static MeetEnums getMeetEnumsByName(String name) {

        MeetEnums[] values = values();

        Optional<MeetEnums> optional = Stream.of(values).filter(v -> v.getName().equals(name)).findAny();

        return optional.isPresent() ? optional.get() : null;

總之枚舉類相比常量來說有太多的優點,它能使得代碼更加整潔美觀、安全性強、功能強大。雖然大部分情況下,枚舉類的選擇是由于常量定義的,但是也并不是任何時候都一定要把常量定義成枚舉;具體情況大家就可以自己去斟酌啦!

繼續閱讀