欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中枚舉的實現(xiàn)與應用詳解

 更新時間:2023年12月20日 10:14:03   作者:Brain_L  
這篇文章主要介紹了Java中枚舉的實現(xiàn)與應用詳解,EnumTest中還有一個VALUES數(shù)組,里面存儲著所有的枚舉實例,調(diào)用values方法時返回VALUES數(shù)組的clone,需要的朋友可以參考下

前言

Java的枚舉和C/C++中的枚舉作用上類似,實現(xiàn)上不一樣。

本文主要探討下Java中枚舉的實現(xiàn)與應用。

如果要定義常量,可能會這樣定義:private static final int SUCCESS = 0;一旦這樣的定義多了之后,就很難管理,容易出錯,甚至重復定義。用枚舉的話就很簡潔清晰。

枚舉原理分析

public enum EnumTest {
    SUCCESS,
    FAILURE,
    EXCEPTION
}

enum是和class、interface同等級的關(guān)鍵字,那么它有什么特殊的地方呢?遇事不決看源碼。。。反編譯看下上面的代碼

public final class EnumTest extends Enum
{
    public static EnumTest[] values()
    {
        return (EnumTest[])$VALUES.clone();
    }
    public static EnumTest valueOf(String s)
    {
        return (EnumTest)Enum.valueOf(com/brain/demo/enumtest/EnumTest, s);
    }
    private EnumTest(String s, int i)
    {
        super(s, i);
    }
    public static final EnumTest SUCCESS;
    public static final EnumTest FAILURE;
    public static final EnumTest EXCEPTION;
    private static final EnumTest $VALUES[];
    static 
    {
        SUCCESS = new EnumTest("SUCCESS", 0);
        FAILURE = new EnumTest("FAILURE", 1);
        EXCEPTION = new EnumTest("EXCEPTION", 2);
        $VALUES = (new EnumTest[] {
            SUCCESS, FAILURE, EXCEPTION
        });
    }
}

枚舉里只有三行,結(jié)果反編譯出來這么多東西。

enum其實就是實現(xiàn)了Enum的類,所以還是先看下Enum這個類。

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {
    private final String name;//枚舉名稱
    private final int ordinal;//序數(shù),從0開始算
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
    public String toString() {
        return name;
    }
    public final boolean equals(Object other) {
        return this==other;
    }
    protected final Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}

兩個主要屬性,name和ordinal。結(jié)合EnumTest反編譯的結(jié)果,初始化時會調(diào)用父類(Enum)的構(gòu)造方法,將name和ordinal傳進去,name是枚舉的名稱,ordinal是聲明的順序(從0開始)。

EnumTest中還有一個VALUES數(shù)組,里面存儲著所有的枚舉實例,調(diào)用values方法時返回VALUES數(shù)組的clone。

調(diào)用valueOf方法時,會調(diào)用Enum的valueOf方法

public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    }
//Class.java
Map<String, T> enumConstantDirectory() {
        if (enumConstantDirectory == null) {
            T[] universe = getEnumConstantsShared();
            if (universe == null)
                throw new IllegalArgumentException(
                    getName() + " is not an enum type");
            Map<String, T> m = new HashMap<>(2 * universe.length);
            for (T constant : universe)
                m.put(((Enum<?>)constant).name(), constant);
            enumConstantDirectory = m;
        }
        return enumConstantDirectory;
    }
T[] getEnumConstantsShared() {
        if (enumConstants == null) {
            if (!isEnum()) return null;
            try {
                final Method values = getMethod("values");
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<Void>() {
                        public Void run() {
                                values.setAccessible(true);
                                return null;
                            }
                        });
                @SuppressWarnings("unchecked")
                T[] temporaryConstants = (T[])values.invoke(null);
                enumConstants = temporaryConstants;
            }
            // These can happen when users concoct enum-like classes
            // that don't comply with the enum spec.
            catch (InvocationTargetException | NoSuchMethodException |
                   IllegalAccessException ex) { return null; }
        }
        return enumConstants;
    }

追著源碼一層層調(diào)用,最后還是調(diào)用values方法,拿到包含所有枚舉實例的數(shù)組。將枚舉的name作為key,實例作為value放入map中。valueOf根據(jù)傳入的name從map中取出對應的實例

枚舉可以用來實現(xiàn)單例,并且是實現(xiàn)單例的最佳方式。關(guān)于為什么枚舉是單例的最佳實現(xiàn),參見另一篇博文——幾種單例的對比。

枚舉應用

除了枚舉自身具備的兩個屬性name和ordinal外,還可以自定義需要的屬性,自定義方法。

public enum EnumTest {
    SUCCESS(0, "調(diào)用成功"),
    FAILURE(1, "調(diào)用失敗"),
    EXCEPTION(-1, "調(diào)用出錯");
    private int status;
    private String msg;
    EnumTest(int status, String msg) {
        this.status = status;
        this.msg = msg;
    }
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getDesc() {
        return status + ":" + msg;
    }
    public static void main(String[] args) {
        System.out.println(EnumTest.FAILURE.getDesc());//1:調(diào)用失敗
    }
}

由于enum實際上是繼承了Enum類,又由于java的單繼承特性,不能再繼承其他類,但是仍可以通過別的方式實現(xiàn)類似的功能。

public enum EnumTest {
    SUCCESS(0, "調(diào)用成功") {
        @Override
        String getDesc() {
            return "恭喜調(diào)用成功";
        }
    },
    FAILURE(1, "調(diào)用失敗") {
        @Override
        String getDesc() {
            return "調(diào)用失敗,請重試";
        }
    },
    EXCEPTION(-1, "調(diào)用出錯") {
        @Override
        String getDesc() {
            return "調(diào)用出錯";
        }
    };
    private int status;
    private String msg;
    EnumTest(int status, String msg) {
        this.status = status;
        this.msg = msg;
    }
    abstract String getDesc();
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

或者干脆實現(xiàn)接口也可以達到同樣的效果。

到此這篇關(guān)于Java中枚舉的實現(xiàn)與應用詳解的文章就介紹到這了,更多相關(guān)Java枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論