枚举详解

目录:


  1. 历史
  2. 枚举的示例
  3. 枚举的好处以及常量类的区别
  4. 枚举常用方法
  5. EnumSet/EnumMap应用
  6. Enum原理简单分析
  7. 总结

1.历史:


枚举是JDK1.5版本新增的特性(泛型、For-each等如今被广泛应用的特性也是由JDK1,5时所新增的),另外到了JDK1.6后switch语句支持枚举类型


2.枚举的示例:


1、天下最简单的版本

public enum PamaEnum {
    RED,BLUE,GREEN
}

2、简单版本

package com.pingan.pafa.cloud.controller;

import java.util.Arrays;
import java.util.List;

public enum PamaEnum {

    SUNNY(1,"晴天",2),
    RAINY(2,"雨天",3),
    CLOUDY(3,"多云",4);

    private int index;
    private String status;
    private int indexs;

    private PamaEnum(int index, String status,int indexs){

        this.index = index;
        this.status = status;
        this.indexs = indexs;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getIndexs() {
        return indexs;
    }

    public void setIndexs(int indexs) {
        this.indexs = indexs;
    }

    public static PamaEnum parse(int index){
        PamaEnum pamaEnum = PamaEnum.SUNNY;
        switch(index){
            case 1:
                pamaEnum = PamaEnum.SUNNY;
                break;
            case 2:
                pamaEnum = PamaEnum.RAINY;
                break;
            case 3:
                pamaEnum = PamaEnum.CLOUDY;
                break;
            default:
              throw new RuntimeException("无此季节下标");
        }
        return pamaEnum;
    }

    public static List<PamaEnum> getEnumValues(){
        return Arrays.asList(values());
    }

    public static void main(String[] args){
        System.out.println(PamaEnum.SUNNY.index + ":" + PamaEnum.SUNNY.status + ":" +PamaEnum.SUNNY.indexs);
        PamaEnum pamaEnum = PamaEnum.CLOUDY;
        System.out.println(pamaEnum.index + ":" + pamaEnum.status);
        List<PamaEnum> list = getEnumValues();
        for (PamaEnum pe : list){
            System.out.println(pe.index + ":" + pe.status);
        }
    }
}

3、枚举的好处以及常量类的区别:


1、枚举型可以直接与数据库打交道,我通常使用varchar类型存储,对应的是枚举的常量名。(数据库中好像也有枚举类型,但是没用过^_^)

2、switch语句支持枚举类,当switch使用int、String类型时,由于值得不稳定性往往会有越界的现象,对于这个的处理往往只能通过if条件刷选以及default模块来处理。而是用枚举型后,在编译期间限定类型,不允许发生越界的情况。如:

package com.pingan.pafa.cloud.controller;

/**
 * 枚举测试类
 */

public enum EnumTest {
    MON, TUE, WED, THU, FRI, SAT, SUM;
}


/**
 *对enum进行便利和switch操作
 */
public class Test {
    
    public static void main(String[] args){
        //遍历
        for (EnumTest e : EnumTest.values()){
            System.out.println(e.toString());
        }
        System.out.println("==============分割线==============");
        EnumTest test = EnumTest.TUE;
        //switch
        switch(test){
            case MON:
                System.out.println("星期一");
                break;
            case TUE:
                System.out.println("星期二");
                break;
            //......
            default:
                System.out.println(test);
                break;
        }
    }
}

3、当你使用常量类时,往往得通过equals去判断两者是否相等,使用枚举的话由于常量值地址唯一,可以用==直接对比,性能会提高。见下源码

 办公网络无法上传截图,我复制过来

 /**
     * Returns true if the specified object is equal to this
     * enum constant.
     *
     * @param other the object to be compared for equality with this object.
     * @return  true if the specified object is equal to this
     *          enum constant.
     */
    public final boolean equals(Object other) {
        return this==other;
    }

4、常量类编译时,是直接把常量的值编译到类的二进制代码里,常量的值在升级中变化后,需要重新编译引用常量的类,因为里面存的是旧值。枚举类编译时,没有把常量值编译到代码里,即使常量的值发生变化,也不会影响引用常量类


4、枚举常用方法介绍:


1、compareTo

int compareTo(E o)

    比较此枚举与指定对象的顺序

2、getDeclaringClass

Class<E> getDeclaringClass()

        返回与此枚举常量的枚举类型相对应的Class对象

3、name()

String name()
        返回此枚举常量的名称,在其枚举声明中对其进行声明

4、ordinal()

int ordinal()

        返回此枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为0)

5、toString()

String toString()

        返回枚举常量的名称,它包含在声明中

6、valueOf

static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)

        返回带指定名称的指定枚举类型的枚举常量

示例:

public static void main(String[] args) {
        PamaEnum p = PamaEnum.SUNNY;
        System.out.println("===============================输出结果==================================");
        //compareTo(E o)
        switch(p.compareTo(PamaEnum.RAINY)){
            case -1:
                System.out.println("TUE 在 MON 之前");
                break;
            case 1:
                System.out.println("TUE 在 MON 之后");
                break;
            default:
                System.out.println("TUE 与 MON 在同一位置");
                break;
        }

        //getDeclaringClass()
        System.out.println("getDeclaringClass():" + p.getDeclaringClass());

        //name()
        System.out.println("name():" + p.name());
        //toString()
        System.out.println("toString():" + p.toString());
        //ordinal() 返回值是从0开始
        System.out.println("ordinal():" + p.ordinal());
    }

运行结果:

===============================输出结果==================================
TUE 在 MON 之前
getDeclaringClass():class com.pingan.pafa.cloud.controller.PamaEnum
name():SUNNY
toString():SUNNY
ordinal():0

5、EnumSet/EnumMap应用


引用示例:

   public static void main(String[] args) {
        //EnumSet用法
        EnumSet<PamaEnum> enumSet = EnumSet.allOf(PamaEnum.class);
        for (PamaEnum p : enumSet){
            System.out.println(p);
        }

        EnumMap<PamaEnum, String> enumMap = new EnumMap(PamaEnum.class);
        enumMap.put(PamaEnum.SUNNY,"阳光明媚");
        enumMap.put(PamaEnum.RAINY,"雨天");
        enumMap.put(PamaEnum.CLOUDY,"多云阴天");
        for (Iterator<Map.Entry<PamaEnum, String>> iter = enumMap.entrySet().iterator();iter.hasNext();){
            Map.Entry<PamaEnum,String> entry = iter.next();
            System.out.println(entry.getKey().name() + ":" + entry.getValue());
        }
    }

 


6、Enum原理简单分析


enum的语法结构尽管和class语法不一样,但是经过编译器编译之后生成一个class文件,该文件经过反编译后可以看到实际上生成了一个类,该类集成了java.lang.Enum<E>,PamaEnum经过javap反编译得到以下内容:

Compiled from "PamaEnum.java"
public final class com.pingan.pafa.cloud.controller.PamaEnum extends java.lang.Enum<com.pingan.pafa.cloud.controller.PamaEnum> {
  public static final com.pingan.pafa.cloud.controller.PamaEnum SUNNY;
  public static final com.pingan.pafa.cloud.controller.PamaEnum RAINY;
  public static final com.pingan.pafa.cloud.controller.PamaEnum CLOUDY;
  public static com.pingan.pafa.cloud.controller.PamaEnum[] values();
  public static com.pingan.pafa.cloud.controller.PamaEnum valueOf(java.lang.String);
  public int getIndex();
  public void setIndex(int);
  public java.lang.String getStatus();
  public void setStatus(java.lang.String);
  public int getIndexs();
  public void setIndexs(int);
  public static com.pingan.pafa.cloud.controller.PamaEnum parse(int);
  public static java.util.List<com.pingan.pafa.cloud.controller.PamaEnum> getEnumValues();
  public static void main(java.lang.String[]);
  static {};
}

从以上代码看出,enum就是一个class,只不过java编译器帮我们做了语法的解析和编译而已


7、总结


我们可以把enum看成是一个普通的class,我们也都可以定义一些属性和方法。特别注意之处是:enum不能使用extends关键字继承其他类,因为enum已经继承了java.lang.Enum(java是单一继承)。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值