Java 枚举(enum)详解

 概念:

Java1.5发行版本中增加了新的引用类型--枚举类型(enum type)。枚举类型是指由一组固定的常量组成合法值的类型。在Java虚拟机中,枚举类在进行编译时会转变成普通的Java类。

创建枚举类型要使用enum关键字,隐含了所创建的类型都是java.lang.Enum类的子类(java.lang.Enum是一个抽象类)。枚举类型的通用格式为Class Enum<E extends Enum<E>>,而E表示枚举类型的名称。枚举类型的每一个值都会映射到protected Enum(String name,int ordinal)构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。源码如下:

/**
 * This is the common base class of all Java language enumeration types.
*/
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
    private final String name;
    private final int ordinal;
    /**
     * Sole constructor.  Programmers cannot invoke this constructor.
     * It is for use by code emitted by the compiler in response to enum type declarations.
    */
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
}

以前我们定义常量都是: public static final....现在好了,当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。

public enum Color {  
  RED, GREEN, BLANK, YELLOW  
}

方法介绍:

 

例 1

下面代码定义了一个表示性别的枚举类型 SexEnum 和一个表示颜色的枚举类型 Color。

public enum SexEnum
{
    male,female;
}
public enum Color
{
    RED,BLUE,GREEN,BLACK;
}

之后便可以通过枚举类型名直接引用常量,如 SexEnum.male、Color.RED。

使用枚举还可以使 switch 语句的可读性更强,例如以下示例代码:

enum Signal
{
    //定义一个枚举类型
    GREEN,YELLOW,RED
}
public class TrafficLight
{
    Signal color=Signal.RED;
    public void change()
    {
        switch(color)
        {
            case RED:
                color=Signal.GREEN;
                break;
            case YELLOW:
                color=Signal.RED;
                break;
            case GREEN:
                color=Signal.YELLOW;
                break;
        }
    }
}

例 2

通过调用枚举类型实例的 values() 方法可以将枚举的所有成员以数组形式返回,也可以通过该方法获取枚举类型的成员。

下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 values() 方法输出这些成员。

enum Signal
{
    //定义一个枚举类型
    GREEN,YELLOW,RED;
}
public static void main(String[] args)
{
    for(int i=0;i<Signal.values().length;i++)
    {
        System.out.println("枚举成员:"+Signal.values()[i]);
    }
}

输出结果如下:

枚举成员:GREEN
枚举成员:YELLOW
枚举成员:RED

例 3

创建一个示例,调用valueOf() 方法获取枚举的一个成员,再调用 compareTo() 方法进行比较,并输出结果。具体实现代码如下:

public class TestEnum
{
    public enum Sex
    {
        //定义一个枚举
        male,female;
    }
    public static void main(String[] args)
    {
        compare(Sex.valueOf("male"));    //比较
    }
    public static void compare(Sex s)
    {
        for(int i=0;i<Sex.values().length;i++)
        {
            System.out.println(s+"与"+Sex.values()[i]+"的比较结果是:"+s.compareTo(Sex.values()[i]));
        }
    }
}

 

上述代码中使用 Sex.valueOf("male") 取出枚举成员 male 对应的值,再将该值与其他枚举成员进行比较。最终输出结果如下:

male与male的比较结果是:0
male与female的比较结果是:-1

例 4

通过调用枚举类型实例的 ordinal() 方法可以获取一个成员在枚举中的索引位置。下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 ordinal() 方法输出成员及对应索引位置。

具体实现代码如下:

public class TestEnum1
{
    enum Signal
    {
        //定义一个枚举类型
        GREEN,YELLOW,RED;
    }
    public static void main(String[] args)
    {
        for(int i=0;i<Signal.values().length;i++)
        {
            System.out.println("索引"+Signal.values()[i].ordinal()+",值:"+Signal.values()[i]);
        }
    }
}

输出结果如下:

索引0,值:GREEN
索引1,值:YELLOW
索引2,值:RED

为枚举添加方法

Java 为枚举类型提供了一些内置的方法,同时枚举常量也可以有自己的方法。此时要注意必须在枚举实例的最后一个成员后添加分号,而且必须先定义枚举实例。

例 5

下面的代码创建了一个枚举类型 WeekDay,而且在该类型中添加了自定义的方法。

enum WeekDay
{
    Mon("Monday"),Tue("Tuesday"),Wed("Wednesday"),Thu("Thursday"),Fri("Friday"),Sat("Saturday"),Sun("Sunday");
    //以上是枚举的成员,必须先定义,而且使用分号结束
    private final String day;
    private WeekDay(String day)
    {
        this.day=day;
    }
    public static void printDay(int i)
    {
        switch(i)
        {
            case 1:
                System.out.println(WeekDay.Mon);
                break;
            case 2:
                System.out.println(WeekDay.Tue);
                break;
            case 3:
                System.out.println(WeekDay.Wed);
                break;
            case 4:
                System.out.println(WeekDay.Thu);
                break;
            case 5:
                System.out.println(WeekDay.Fri);
                break;
            case 6:
                System.out.println(WeekDay.Sat);
                break;
            case 7:
                System.out.println(WeekDay.Sun);
                break;
            default:
                System.out.println("wrong number!");
        }
    }
    public String getDay()
    {
        return day;
    }
}

上面代码创建了 WeekDay 枚举类型,下面遍历该枚举中的所有成员,并调用 printDay() 方法。示例代码如下:

public static void main(String[] args)
{
    for(WeekDay day:WeekDay.values())
    {
        System.out.println(day+"====>"+day.getDay());
    }
    WeekDay.printDay(5);
}

输出结果如下:

Mon====>Monday
Tue====>Tuesday
Wed====>Wednesday
Thu====>Thursday
Fri====>Friday
Sat====>Saturday
Sun====>Sunday
Fri

Java 中的 enum 还可以跟 Class 类一样覆盖基类的方法。下面示例代码创建的 Color 枚举类型覆盖了 toString() 方法。

public class Test
{
    public enum Color
    {
        RED("红色",1),GREEN("绿色",2),WHITE("白色",3),YELLOW("黄色",4);
        //成员变量
        private String name;
        private int index;
        //构造方法
        private Color(String name,int index)
        {
            this.name=name;
            this.index=index;
        }
        //覆盖方法
        @Override
        public String toString()
        {
            return this.index+"-"+this.name;
        }
    }
    public static void main(String[] args)
    {
        System.out.println(Color.RED.toString());    //输出:1-红色
    }
}

EnumMap 与 EnumSet

为了更好地支持枚举类型,java.util 中添加了两个新类:EnumMap 和 EnumSet。使用它们可以更高效地操作枚举类型。具体就后面再说吧。

posted @ 2019-11-19 19:02  广金  阅读(748)  评论(0编辑  收藏  举报