java——枚举类

枚举类

      在某些情况下,一个累的对象是有限而且固定的,比如季节类,它只有4个对象(春、夏、秋、冬);再比如交通灯类,只有3个对象(红、绿、黄)。这种实例有限而且固定的类,在Java里被称为枚举类。

以前与现在的枚举类的对比

      在早期代码中,可能会直接使用简单的静态常量来表示枚举,例如以下代码:

public class State {
public static final int ON = 1;
public static final Int OFF= 0;
}

      这种方法虽然简单简单明了,但存在如下几个问题:

      1. 类型不安全:因为上面的每个state实际上是一个int整数,因此完全可以把一个季节当成一个int整数使用,例如进行加法运算 ON+OFF,这样的代码完全正常。

      2. 打印输出的意义不明确:当输出某个state时,例如输出 ON时,实际输出的是1,这个1很难猜测它代表了ON。

      但枚举又确实有存在的意义,因此早期也可以通过定义类的方式来实现,可以采用如下设计方式:

      1. 通过private将构造器隐藏起来。

      2. 把这个类的所有可能实例都使用public static final修饰的类变量来保存。

      3. 如果有必要,可以提供一些静态方法,允许其他程序根据特定参数来获取与之匹配的实例。

      4. 使用枚举类可以使程序更加健壮,避免创建对象的随意性。

      但通过定义类来实现枚举的代码量比较大,实现起来也比较麻烦,Java从JDK1.5后就增加了对枚举类的支持。

枚举类入门

      Java 5新增了一个enum关键字(它与class、interface关键字的地位相同),用于定义枚举类。正如前面看到的,枚举类是一种特殊的类,它一样可以有自己的成员变量、方法,可以实现一个或者多个接口,也可以定义自己的构造器。一个Java源文件中最多只能定义一个public访问权限的枚举类,且该Java源文件也必须和该枚举类的类名相同。

      但是枚举类终究不是普通类,它与普通类有如下简单的区别:
      1. 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是默认继承Object类,因此枚举类不能显式继承其它类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。

      2.使用enum定义、非抽象的枚举类默认会使用final修饰,因此枚举类不能派生子类。

      3. 枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远都不能产生实例。列出这些实例的时候,系统会自动添加public static final修饰,无需程序员显式添加。

      4.枚举类的构造器只能使用private访问控制符,如果省略的默认的构造器的访问控制符,则默认使用private修饰;如果强制指定访问控制符,则只能指定private修饰符。

      枚举类默认提供一个values()方法,该方法可以很方便的遍历所有的枚举值。

package knowledge;

enum SeasonEnum{
    Spring,Summer,Fall,Winter;
}

public class enum1 {

    public static void judge(SeasonEnum s){

        // switch 与距离的表达式可以是枚举值
        switch (s)
        {
        case Spring :
            System.out.println("春暖花开");
            break;
        case Summer :
            System.out.println("夏日炎炎");
            break;
        case Fall :
            System.out.println("秋高气爽");
            break;
        case Winter :
            System.out.println("冬日雪飘");
            break;
        }
    }

    public static void main(String[] args) {
        // 枚举类默认有一个values()方法,返回该枚举类的所有实例

        for(SeasonEnum s:SeasonEnum.values())
        {
            System.out.println(s);
        }

        //使用枚举实例时,可通过EnumClass.variable形式来访问
        enum1.judge(SeasonEnum.Spring);
    }

}

这里写图片描述

图1 代码运行结果图

      java.lang.Enum类中提供了几个常用的如下的方法:。
      1. String name():返回此枚举实例的名称,这个名称就是定义枚举时列出的所有枚举值之一。与此方法相比,大多数程序员应该优先考虑使用toString()方法,因为toString方法返回更加友好的名称。

      2. int ordinal():返回枚举值在枚举类中的索引值(就是枚举值在声明中的位置,第一个枚举值的索引值为零)。

      3. String toString():返回枚举常量的名称,与name方法相似,单toString()方法更常用。

      枚举类型的完整演示代码如下:

package knowledge;

import java.util.EnumMap;
import java.util.EnumSet;

public class enumtest {

    // 1. 定义枚举类型
    public enum Light {
       // 利用构造函数传参
       RED (10), GREEN (3), YELLOW (2);

       // 定义私有变量
       private int nCode ;

       // 构造函数,枚举类型只能为私有
       private Light( int _nCode) {
           this . nCode = _nCode;
       }

       @Override
       public String toString() {
           return String.valueOf ( this . nCode );
       }
    }

    /**
      * @param args
      */
    public static void main(String[] args ) {

       // 1. 遍历枚举类型
       System. out .println( " 演示枚举类型的遍历 ......" );
       testTraversalEnum ();

       // 2. 演示 EnumMap 对象的使用
       System. out .println( " 演示 EnmuMap 对象的使用和遍历 ....." );
       testEnumMap ();

       // 3. 演示 EnmuSet 的使用
       System. out .println( " 演示 EnmuSet 对象的使用和遍历 ....." );
       testEnumSet ();

       System.out.println();
    }

    /**
      * 演示枚举类型的遍历
      */
    private static void testTraversalEnum() {
       Light[] allLight = Light.values ();
       for (Light aLight : allLight) {
           System. out .println( " 当前灯 name : " + aLight.name());
           System. out .println( " 当前灯 ordinal : " + aLight.ordinal());
           System. out .println( " 当前灯: " + aLight);
       }
    }

    /**
      * 演示 EnumMap 的使用, EnumMap 跟 HashMap 的使用差不多,只不过 key 要是枚举类型
      */
    private static void testEnumMap() {
       // 1. 演示定义 EnumMap 对象, EnumMap 对象的构造函数需要参数传入 , 默认是 key 的类的类型
       EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(
              Light. class );
       currEnumMap.put(Light. RED , " 红灯 " );
       currEnumMap.put(Light. GREEN , " 绿灯 " );
       currEnumMap.put(Light. YELLOW , " 黄灯 " );

       // 2. 遍历对象
       for (Light aLight : Light.values ()) {
           System. out .println( "[key=" + aLight.name() + ",value="
                  + currEnumMap.get(aLight) + "]" );
       }
    }

    /**
      * 演示 EnumSet 如何使用, EnumSet 是一个抽象类,获取一个类型的枚举类型内容 <BR/>
      * 可以使用 allOf 方法
      */
    private static void testEnumSet() {
       EnumSet<Light> currEnumSet = EnumSet.allOf (Light. class );
       for (Light aLightSetElement : currEnumSet) {
           System. out .println( " 当前 EnumSet 中数据为: " + aLightSetElement);
       }

    }
}

这里写图片描述

图2 枚举类型的完整演示代码结果图

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值