天天看點

Java枚舉你真的會用嗎

作者:沒有煩惱的河豚

概述

Java中枚舉,大家在項目中經常使用吧,主要用來定義一些固定值,在一個有限的集合内,比如在表示一周的某一天,一年中的四季等。那你了解枚舉的本質嗎?了解枚舉的一些常見用法嗎?

枚舉介紹和使用

枚舉主要用來定義一個有限集合内的固定值。

枚舉定義方式如下:

// 簡單的定義
enum WeekEnum {
    MONDAY, TUESDAY
}

// 有屬性的定義
enum StatusEnum {
    ENABLE("1", "啟用"), DISABLE("0", "禁用");

    private String code;

    private String name;

    StatusEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}           

枚舉編譯後實際上繼承了java.lang.Enum這個類,後面詳細講解,我們看下這個類的關鍵方法:

  • static Enum valueOf(Class enumClass, String name)

傳回指定名字、給定類的枚舉常量

  • String toString()

傳回枚舉常量名

  • int ordinal()

傳回枚舉常量在enum中的位置,從0開始

  • int compareTo(E other)

如果枚舉場景出現在other之前,則傳回一個負值,如果this == other,則傳回0,否則傳回正值。

public static void main(String[] args) {
        // 根據字元串擷取枚舉
        StatusEnum enable = Enum.valueOf(StatusEnum.class, "ENABLE");
        System.out.println(enable);
        //枚舉比較直接用==
        System.out.println(enable == StatusEnum.ENABLE);

        // values方法擷取所有的枚舉
        StatusEnum[] values = StatusEnum.values();
        for (StatusEnum statusEnum : values) {
            // 列印枚舉的位置
            System.out.println(statusEnum.ordinal());
        }
    }           

運作結果:

Java枚舉你真的會用嗎

枚舉的本質

枚舉的本質其實一個類,繼承了java.lang.Enum這個類。我們可以用idea的插件看下生成的位元組碼如下:

  1. 繼承了java.lang.Enum
Java枚舉你真的會用嗎
  1. ENABLE、DISABLE最終轉換為靜态字段,類型其實StatusEnum這個類
Java枚舉你真的會用嗎
  1. 類加載的時候初始化ENABLE、DISABLE這兩個屬性。
Java枚舉你真的會用嗎

方法是類加載的初始化階段就是執行的,它這裡的主要邏輯就是建立了兩個對象,設定到ENABLE,DISABLE上。

這下你明白枚舉是怎麼一回事情了吧。

枚舉常見用途

枚舉建立單例

枚舉可以作為單例模式的最佳方式,能夠保證單例對象的唯一性。

public class User {
    //私有化構造函數
    private User(){ }
 
    //定義一個靜态枚舉類
    static enum SingletonEnum{
        //建立一個枚舉對象,該對象天生為單例
        INSTANCE;
        private User user;
        //私有化枚舉的構造函數
        private SingletonEnum(){
            user = new User();
        }
        public User getInstnce(){
            return user;
        }
    }
 
    //對外暴露一個擷取User對象的靜态方法
    public static User getInstance(){
        return SingletonEnum.INSTANCE.getInstnce();
    }
}           
  • 枚舉INSTANCE會在類加載初始化的時候建立,而Java類的加載和初始化過程都是線程安全的。
  • 枚舉可避免反序列化破壞單例。

枚舉抽象方法

枚舉類可以定義抽象方法,然後讓各個具體的枚舉實作,可以通過枚舉實作不同的政策實作。

enum OperEnum {
    ADD(1, 2) {
        @Override
        public Integer operate() {
            return this.getA() + this.getB();
        }
    }, MULTIPY(1, 2) {
        @Override
        public Integer operate() {
            return this.getA() * this.getB();
        }
    };

    private Integer a;

    private Integer b;

    OperEnum(Integer a, Integer b) {
        this.a = a;
        this.b = b;
    }

    public abstract Integer operate();

    public Integer getA() {
        return a;
    }

    public void setA(Integer a) {
        this.a = a;
    }

    public Integer getB() {
        return b;
    }

    public void setB(Integer b) {
        this.b = b;
    }
}           

總結

本文主要講解了枚舉的本質,以及枚舉的常見用法,希望對你們有幫助。

繼續閱讀