Java enum列舉類詳解 列舉的常見用法

fuua發表於2021-01-04

什麼時候用列舉?

類的物件是有限個的確定的時候,可以考慮用列舉,例如

Thread.State(執行緒的狀態):建立,就緒,執行,阻塞,死亡

星期:週一...週日

季節:Spring , Summer,Autumn,Winter

等一系列一組常量的定義時,強烈建議使用列舉類

相信不少同學第一次接觸enum的時候很迷茫,這個關鍵字是什麼意思?程式碼這樣寫有什麼意義?

enum是jdk1.5版本提供的列舉關鍵字,看看enum出之前如何定義列舉類的,相信不少小夥伴看完能豁然開朗

這裡就以季節為例

//不使用enum的方式定義列舉類
class Season {
    //定義列舉類屬性
    private final String SeasonName;

    //私有化構造方法,初始化季節值
    private Season(String seasonName) {
        this.SeasonName = seasonName;
    }

    //建立春夏秋冬靜態物件
    public static final Season SPRING = new Season("Spring");
    public static final Season SUMMER = new Season("Summer");
    public static final Season AUTUMN = new Season("Autumn");
    public static final Season WINTER = new Season("Winter");

    //重新toSring
    @Override
    public String toString() {
        return "Season{" +
                "SeasonName='" + SeasonName + '\'' +
                '}';
    }

    //獲取屬性
    public String getSeasonName() {
        return SeasonName;
    }


}

 

 Season season = Season.AUTUMN;
        

上述程式碼即可建立一個列舉類例項,對不熟悉enum的同學來說這種寫法相信更容易理解,而且看起來與單例餓漢式有點相似,事實上單例模式完全可以用列舉類定義

那enum有什麼區別呢?我把上面的程式碼用enum定義來看看

enum Season {
    //定義列舉靜態物件
    //原始碼
/*    public static final Season SPRING = new Season("Spring");
    public static final Season SUMMER = new Season("Summer");
    public static final Season AUTUMN = new Season("Autumn");
    public static final Season WINTER = new Season("Winter");*/
   //省略了public static final 以及new 物件的操作 必須放在類首行
    SPRING("Spring"),//使用,做間隔
    SUMMER("Summer"),
    AUTUMN("Autumn"),
    WINTER("Winter");

    private final String SeasonName;


    private Season(String seasonName) {
        this.SeasonName = seasonName;
    }

    @Override
    public String toString() {
        return "Season{" +
                "SeasonName='" + SeasonName + '\'' +
                '}';
    }

    public String getSeasonName() {
        return SeasonName;
    }

}

很明顯能看出來,省略了new物件和public static final的修飾詞,那除此之外還有什麼區別呢

在方法裡測試的時候,可以很清楚的看到,Season除了四個列舉常量之外還有三個方法,一個values,一個valusOf以及他的過載方法

那這三個方法是從哪裡來的呢,難不成enum物件不是直接繼承的Object嗎,別急我們列印出來看一下

System.out.println(Season.class.getSuperclass());

輸出結果是class java.lang.Enum

看來enum關鍵字修飾的列舉類,預設繼承於java.lang.Enum

java.lang.Enum也又幾個常用的方法

values(),返回的是一個包括所有列舉類物件的陣列,方便遍歷,但是用Arrays.toString()不能直接輸出,必須自己親自遍歷

valueOf(String )是通過元素名字獲取列舉類物件

enum中的toSring方法也重寫過了,預設輸出列舉類物件名,如有需要可以自己重寫

既然enum相當於一個預設繼承了 java.lang.Enum的列舉類,那他可不可以實現介面,或者繼承/被繼承呢

先說繼承,既然他已經預設繼承於 java.lang.Enum,那他當然不能繼承別的類了,另外,因為構造方法私有化的原因,當然也不可以被別的類繼承

那麼說說介面,既然本質上還是一個普通的類,那自然是可以實現介面的,而且實現方式和別的類也沒什麼區別

//使用enum關鍵字使用介面
interface Info {
    void show();
}


enum Season implements Info{

    //定義列舉靜態物件
    SPRING("Spring"),
    SUMMER("Summer"),
    AUTUMN("Autumn"),
    WINTER("Winter");
    private final String SeasonName;


    Season(String seasonName) {
        this.SeasonName = seasonName;
    }

    @Override
    public String toString() {
        return "Season{" +
                "SeasonName='" + SeasonName + '\'' +
                '}';
    }

    public String getSeasonName() {
        return SeasonName;
    }

    @Override
    public void show() {
        System.out.println("這是一個季節");
    }
}

還可以給不同的列舉類物件獨立的實現方法,如下

  //定義列舉靜態物件
    SPRING("Spring"){
        @Override
        public void show() {
            System.out.println("This is Spring ");
        }
    },


關於列舉類大概就說到這裡了,水平有限,有什麼錯誤或者想補充的都可以在評論區指出

相關文章