目录

1.枚举类的定义

2.枚举类的使用

3.枚举类的作用与优点


1.枚举类的定义

在编程开发中,我们经常遇到诸如此类的问题——一组颜色有红、橙、黄、绿、青、蓝、紫,而且这些颜色都是常量固定不变,因此我们需要专门来定义一个类用来存放这些常量以便于使用。

/**
 * 一个专门用来容纳颜色的类
 */
public class Color {
    
    //创建颜色,这些颜色可以用类调用,且地址不可改变
    public static final Color GREEN = new Color("绿色");
    public static final Color RED = new Color("红色");
    public static final Color Yellow = new Color("黄色");
    public static final Color BLUE = new Color("蓝色");
    public static final Color WHITE = new Color("白色");
    public static final Color BLACK = new Color("黑色");
    
    private final String name;//颜色名
    private final int index;//颜色索引
    
    private static int count = 0;//计数器

    //私有化的构造方法:只能在类内部实例化对象
    private Color(String name){
        this.name = name;
        this.index = count;
        count++;//每创建一个颜色索引向后移
    }
    
    //获取颜色的名字和索引
    public String getName() {
        return name;
    }
    public int getIndex() {
        return index;
    }
}

上面所定义的类就实现了对一组颜色的存放,使用者也可以通过方法获取每种颜色的具体属性。同时该类也禁止使用者自定义颜色,使用者只能够调用已有的颜色。下面我们使用一下这个类。

public static void main(String[] args) {

        //使用黑色
        System.out.println(Color.BLACK.getName() + "的编号是:" + Color.BLACK.getIndex());

        //使用红色
        System.out.println(Color.RED.getName() + "的编号是:" + Color.RED.getIndex());
    }

    结果为:

    BLACK的编号是:5
    RED的编号是:1

其实在早期并没有枚举类,大部分情况都是按照上面的方式实现的。直到 JDK1.5 时才引入了枚举类,枚举类对上面所示代码进行了简化,并提供了一些额外的方法供开发者使用。

Java 中的每一个枚举都继承自抽象类 java.lang.Enum <T> 。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public、 static 修饰。

2.枚举类的使用

我们还是拿刚才颜色的例子,用枚举类来实现。此时只需要很简单的几行代码,就完成了上面的所有工作。

//枚举类用enum不用class
public enum ColorEnum {

    GREEN,RED,Yellow,BLUE,WHITE,BLACK;
    
}

下面我们同样使用一下枚举类。

public static void main(String[] args) {

        //其中的name()/toString()和ordinal()方法分别对应上面的getName()与getIndex()方法

        //使用黑色
        System.out.println(ColorEnum.BLACK.toString() + "的编号是:" + ColorEnum.BLACK.ordinal());

        //使用红色
        System.out.println(ColorEnum.RED.name() + "的编号是:" + ColorEnum.RED.ordinal());
    }

    结果为:

    BLACK的编号是:5
    RED的编号是:1

很明显,用枚举类达到了同样的效果。枚举类的使用方便程度可不止于此,除了上面所演示的的三个方法外,枚举类还有四个极具特点的方法可供我们参考。

public static void main(String[] args) {

        //1.values()方法:给出枚举类中的所有实例化对象数组,此处使用了多态的写法
        ColorEnum[] colorEnums = ColorEnum.values();
        for (int i = 0; i < colorEnums.length; i++) {
            System.out.print(colorEnums[i].toString() + ",");
        }

        //2.equals()方法:判断枚举类中的实例化对象是否相同
        System.out.println(ColorEnum.GREEN.equals(ColorEnum.GREEN));//true
        System.out.println(ColorEnum.GREEN.equals(ColorEnum.BLACK));//false

        //3.valueOf()方法:把与枚举类中实例化对象名相同的字符串转成枚举类对象
        ColorEnum green = ColorEnum.valueOf("GREEN");
        System.out.println(green.equals(ColorEnum.GREEN));//true

        //4.compareTo()方法:比较两个枚举类的索引值并返回差值
        System.out.println(ColorEnum.GREEN.compareTo(ColorEnum.RED));
    }

    结果为:

    GREEN,RED,Yellow,BLUE,WHITE,BLACK,
    true
    false
    true
    -1

由于这三个方法的实现涉及到了 Java 反射机制的内容,对于其源码的深入探究放在 Java 反射机制学习完之后;在此只需要会使用枚举类中的方法即可。

注意:

①在枚举类中也可以定义成员属性、成员方法以及私有化(默认)的构造方法。

②枚举类的实例化对象必须写在类代码的第一行。

③枚举类的实例化对象默认都是 public static final 的;而成员属性一般为 private final 的,由构造方法为其赋值。从安全角度考虑,成员属性只应该有 getter 方法。

④枚举类的构造器都是 private 的,所以无法在外部创建其实例,这也决定了枚举类实例的个数的确定性(写了几个就是几个)。

⑤枚举类不可被继承,但是可以实现接口。

⑥枚举类默认 extends java.lang.Enum ,所以无法再继承其他类。

3.枚举类的作用与优点

(1)枚举类提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。

(2)类型安全;弥补了单例模式中在反射时会创建新的实例所带来的缺陷。

(3)紧凑有效的数据定义,防止数据越界,枚举实例的索引自动生成,无需外加干预。

(4)提高了程序的运行效率。