Java枚举类型

一、枚举的定义

什么是枚举?

        枚举是一个被命名的整型常数的集合,用于声明一组带标识的常数。枚举在日常生活中很常见,例如:一个人的性别只能是“男”或“女”,一周的星期只能是7天中的一个等。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。

枚举的定义

声明枚举时必须使用enum关键字,然后定义枚举的名称、可访问性、基础类型和成员等。枚举申明语法如下:

enum-modifiers enum enumname:enum-base{
    enum-body,
}

其中,enum-modifiers表示,枚举的修饰主要包括public、private和internal;enumname表示声明的枚举名称;enum-base表示基础类型;enum-body表示枚举成员,它是枚举类型的命名常数。

任意两个枚举成员不能具有相同的名称,且他的常数值必须在该枚举的基础类型范围之内,多个枚举成员之间使用逗号分隔。

提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是int。

enum Color{
    RED,GREEN,BLUE;
}
//以上枚举Color颜色常量有RED,GREEN,BLUE,分别表示红色,绿色,蓝色。
public class Test
{
//执行输出结果
    public static void main(string[] args)
{
    Color c1 = Color.RED;
    System.out.println(c1);
}
}
//输出结果为:RED

二、Enum类的主要方法

        java中的每一个枚举都继承自java.lang.Enum类,并实现java.lang.Aeriablizable和java.lang.Comparable两个接口。当定义一个枚举类型时,每一个枚举类型成员都可以看作是Enum类的实例,这些枚举成员默认值都被final、public、static修饰,当使用枚举成员时,直接使用枚举名称调用即可。

        所有枚举实例都可以调用Enum类的方法。

      

Enum类的主要方法
valueOf

传递枚举类型的Class对象和枚举常量名称给静态方法valueOf,舍得到与其参数匹配的枚举常量。

toString得到当前枚举常量的名称,你可以通过重写这个方法来使得到的结果更易读。
equals在枚举类型中可以直接使用“==”来比较两个枚举常量是否相等。Enum提供的这个equals()方法,也是直接使用“==”实现的。它的存在是为了在Set、List和Map中使用。注意,equals()是不可改变的。
hashCodeEnum实现了hashCode()来和equals()保持一致
getDeclaringClass得到当前枚举类型常量的名称。建议优先使用toString()。
name得到当前枚举常量的名称。建议优先使用toString()。
compareTo枚举类型实现哦了Compareable接口,这样可以比较两个枚举常量的大小(按照声明的顺序排列)
chone枚举类型不能Clone。为了防止子类实现克隆方法,Enum实现了一个仅输出CloneNotSupportedException异常的不变Clone()。

通过调用枚举类型实例的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
*/

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

public class TestEnum {
       public enum Sex{
        //定义一个枚举
        male,female;
}
    public static void main(String[] args){
        compare (Sex.valueOf("male"));
}
    public static void main compare(Sex s){
        for (int i=0;i<Sex.values().length){
            System.out.println(s+"与"+Sex.values()[i]+"的比较结果是:"+s.compareTo(Sex.vales()[i]));
            }
    }
}
/*上述代码中使用Sex.valueOf("male")取出枚举成员male对应的值,再将该值与其他枚举成员进行比较。最终输出结果如下:
male与male的比较结果是:0
male与female的比较结果是:-1*/

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

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

三、枚举的使用

用法一:常量

          在JDK1.5 之前,我们定义常量都是: public static final.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

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

用法二:switch

      JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。 

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; 
        }   
    } 
}

  

用法三:向枚举中添加属性

            可以在创建枚举成员添加属性,但必须满足以下两个条件:

            1、要在类中声明该属性

            2、一定要有属性的构造方法(必须private)

enum   WeekDay {
    // 定义枚举成员,并添加属性(相当于构造函数)
      Mon("Monday"),Tue("Tuesday"),Wed("Wednesday"),Thu("Thursday"),
      Fri("Friday"),Sat("Saturday"),Sun("Sunday");
   
    // 声明属性,并创建构造函数(必须private)
    private final String day;
    private WeekDay(String day) {
        this.day = day;
    }
}

用法四:向枚举中添加新方法

            如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。

            可以在枚举类中添加任意方法,像class一样。方法一般分两种:

            ·       枚举常量方法:如get()/set()等修改获取属性的方法

            ·       定义时不加 static

            ·       在使用时通过 WeekDay.Mon.getDay()调用

            ·       枚举类方法:如根据数字打印日期printDay()

            ·       必须声明成 static

            ·       在使用时通过WeekDay.printDay()调用

enum WeekDay {
    // 定义枚举成员,并添加属性
      Mon("Monday"),Tue("Tuesday"),Wed("Wednesday"),Thu("Thursday"),
      Fri("Friday"),Sat("Saturday"),Sun("Sunday");
   
    // 声明属性,并创建构造函数(必须private)
    private final String day;
    private WeekDay(String day) {
        this.day = day;
    }
   
    // 1.根据输入的i打印相应周几,属性无关方法,一定要static
    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!");
        }
    }
   
    // 2.返回当前枚举成员中定义的属性
    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-红色
    }
}

四、枚举的工具

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

EnumMap

EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map(如 HashMap)实现也能完成枚举类型实例到值的映射,但是使用 EnumMap 会更加高效。

HashMap 只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值,使得 EnumMap 的效率非常高。

下面是使用 EnumMap 的一个代码示例。枚举类型 DataBaseType 里存放了现在支持的所有数据库类型。针对不同的数据库,一些数据库相关的方法需要返回不一样的值,例如示例中 getURL() 方法。

//   定义数据库类型枚举
public   enum DataBaseType {
    MYSQUORACLE,DB2,SQLSERVER
}
//   某类中定义的获取数据库URL的方法以及EnumMap的声明
private   EnumMap<DataBaseType,String>urls = new   EnumMap<DataBaseType,String>(DataBaseType.class);
 
public   DataBaseInfo() {
      urls.put(DataBaseType.DB2,"jdbc:db2://localhost:5000/sample");
    urls.put(DataBaseType.MYSQL,"jdbc:mysql://localhost/mydb");
      urls.put(DataBaseType.ORACLE,"jdbc:oracle:thin:@localhost:1521:sample");
      urls.put(DataBaseType.SQLSERVER,"jdbc:microsoft:sqlserver://sql:1433;Database=mydb");
}
//根据不同的数据库类型,返回对应的URL
//   @param type DataBaseType 枚举类新实例
//   @return
public   String getURL(DataBaseType type) {
    return this.urls.get(type);
}

在实际使用中,EnumMap 对象 urls 往往是由外部负责整个应用初始化的代码来填充的。这里为了演示方便,类自己做了内容填充。

从这个例子中可以看出,使用 EnumMap 可以很方便地为枚举类型在不同的环境中绑定到不同的值上。本例子中 getURL 绑定到 URL 上,在其他的代码中可能又被绑定到数据库驱动上去。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangkay88

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值