Java枚舉

Java枚舉有如下特點:

  • 枚舉類省略了private類型的構造函數,且構造函數只能爲私有;
  • 枚舉的域(field)實質就是相應的枚舉類的一個實例對象;
  • 當訪問枚舉的實例(域)時纔會執行構造方法實例化,例如下面的DAY實例只有被訪問時纔會被創建;
  • 枚舉的實例(域)都被static final修飾,保證了只能被實例化一次;
  • 編譯器會自動爲枚舉繼承java.lang.Enum的類,所以代碼中枚舉只能實現接口而不能再繼承其他類;

枚舉原理

下面看一個簡單的枚舉類:

package com.faith.net;

/**
 * 日期類型
 */
public enum DateType {

    DAY;
}

上面的代碼在編譯後實際等同於:

public class DateType extends Enum {

    public static final DateType DAY;
    
    private DateType () {}
}

可以把DateType看做一個類,而Day是DateType的一個實例。它的構造方法則是私有的。

枚舉添加靜態變量/方法和成員變量/方法

枚舉中也可以添加靜態變量、靜態方法和成員變量、成員方法:

public enum DateType {

    DAY;
    
    static int value;
    public static int getValue() {
        return value;
    }

    String name;
    public String getName() {
        return name;
    }
}

我們把DateType看做一個類,靜態變量和靜態方法和普通類調用方式一樣:

DateType.value
DateType.getValue()

成員變量和成員方法是每個類的實例才能調用的方法。而枚舉類的實例就是它的域。所以調用枚舉的成員變量和方法,通過如下方式:

DateType.DAY.name
DateType.DAY.getName()

重寫枚舉成員方法

枚舉的每個實例(域)還可以重寫枚舉中的成員方法,類似於多態,如下:

public enum DateType {

    DAY {
        public Integer getValue() {
            return 0;
        }
    };
    
    static Integer value = 1;
    public static Integer getValue() {
        return value;
    }

    String name;
    public String getName() {
        return name;
    }
}

DAY中重寫了getValue方法,重寫前DateType.DAY.getValue()值爲1,重寫後則調用DAY中自己定製的getValue方法,結果爲0。

枚舉添加抽象方法

還可以在枚舉中添加抽象方法,強制所有實例(域)都實現各自的處理邏輯:

public enum DateType {

    DAY {
        @Override
        public String getText() {
            return null;
        }
    },

    WEEK {
        @Override
        public String getText() {
            return null;
        }
    };

    public abstract String getText(); // 抽象方法,強制所有實例實現
}

枚舉實現接口

強制實例必須實現方法還可以通過實現接口:

public interface NameEnum {
    String getName();
}
public enum DateType implements NameEnum {

    DAY {
        @Override
        public String getName() {
            return null;
        }
    },

    Week {
        @Override
        public String getName() {
            return null;
        }
    };
}

帶參構造

枚舉使用帶參構造函數:

package com.faith.net;

import java.util.HashMap;
import java.util.Map;

/**
 * 日期類型
 *
 * @author hugende
 */
public enum DateType {

    DAY("sdfsdf", 0) {
        @Override
        public String getText() {
            return null;
        }
    },

    WEEK("sdf", 1) {
        @Override
        public String getText() {
            return null;
        }
    };

    public abstract String getText();

    String name;
    Integer age;
    
    DateType(String name, Integer age) {
        this.name = "s";
        this.age = age;
    }
}

訪問方式如下:

DateType.DAY.name  // 0
DateType.WEEK.name // 1

遍歷枚舉

枚舉提供了values方法:

public class EnumTest {

    public static void main(String[] args) {
        DateType[] values = DateType.values();
        for (DateType dateType : values) {
            System.out.println(dateType.age);
        }
    }
}

枚舉的父類

Java強制枚舉實現了Enum類,這個類的聲明如下:

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable

可見其實現了Comparable、Serializable,支持了比較與序列化傳輸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章