java枚举类型enum用法_枚举到底是个什么鬼类型?

bf9bb4cf903654a7dd4129544a05ff4a.png

前言

枚举是很多面向对象语言都会有的一种类型,它可以将表达同一类型的变量组合成一个集合,组成一个常量集

在Java中也有枚举类型,是用enum关键字来表示的

枚举常用来表示一个常量集,用来限定变量的取值,只能在枚举的范围内,比如一年四季只有春、夏、秋、冬、一个星期只有周一到周日,这类固定的常量就比较适合用枚举来表达

当然你说我用静态的常量来表达行不行呢?也是可以的,只是枚举就是为这种场景而生的

枚举这种类型其实没什么存在感,大家在使用的时候也是使用最基本的用法,甚至很多人都不用枚举,至少我自己在写这篇文章之前是很少用 枚举类型的,经常会用静态常量来代替枚举,但枚举确实有他的好处,下面我们就一起来看一下

枚举的简单用法

public enum OrderState {    ORDER_CONFIRM,ORDER_PAYED,ORDER_DELIVERY,ORDER_FINISH}

OrderState列举了订单的几种状态

  • ORDER_CONFIRM 订单已确认
  • ORDER_PAYED 订单已支付
  • ORDER_DELIVERY 订单已出库
  • ORDER_FINISH 订单已完成
OrderState orderState = OrderState.ORDER_FINISH;System.out.println(orderState);

在使用枚举类型时,需要定义一个枚举类型的对象,如上代码,执行结果如下:

ORDER_FINISH

枚举类型常用的方法

  • values() 返回所有的枚举值数组
  • ordinal() 表示枚举值在枚举类型中的次序,从0开始
  • compareTo() 用于比较两个枚举类型
  • name() 返回枚举值
// values()返回所有的枚举值for (OrderState os :OrderState.values()) {    //枚举值的次序    System.out.println(os + "|" + os.ordinal());    //比较    System.out.println(os.compareTo(OrderState.ORDER_FINISH));    //枚举值    System.out.println(os.name());    System.out.println("------------------");}

向枚举中添加方法

在枚举的简单用法中,枚举类里面只定义了几个常量,其实枚举类型中还可以增加方法

public enum OrderState {    ORDER_CONFIRM(0,"订单已确认"),ORDER_PAYED(1,"订单已支付"),ORDER_DELIVERY(2,"订单已支付"),ORDER_FINISH(3,"订单已完成");    private int state;    private String stateText;    OrderState(int state,String stateText){        this.state = state;        this.stateText = stateText;    }    public int getState(){        return state;    }    public String getStateText(){        return stateText;    }    public static void main(String[] args){        for(OrderState orderState : OrderState.values()){            System.out.println(orderState + "|" + orderState.getState() + "|" + orderState.getStateText());        }    }}

从上面的代码可以看出来,枚举类型可以有构造方法,也可以有普通方法,枚举跟类很像,或者说它就是一种拥有限制的类

switch中的枚举

枚举跟switch语句简直是天造地设的一对,switch中可以天然的支持枚举类型

switch (orderState){    case ORDER_CONFIRM:        System.out.println(orderState.getState());        break;    case ORDER_PAYED:        System.out.println(orderState.getStateText());        break;    case ORDER_DELIVERY:        System.out.println(orderState.getState());        break;    case ORDER_FINISH:        System.out.println(orderState.getStateText());        break;}

枚举的真面目

我们用编译/反编译的方法来看一下枚举到底是个什么鬼类型

首先编译OrderState.java文件,注意你的枚举类型中有中文需要加-encoding参数用UTF-8进行编码,否则会编译不通过

javac -encoding UTF-8 OrderState.java

执行完成后,在同一目录下会生成一个OrderState.class文件,我们反编译回来

javap -p OrderState.class

会得到如下的代码

//枚举就是一个继承自Enum的类public final class org.kxg.enumDemo.OrderState extends java.lang.Enum {  //枚举中的常量就是类的静态变量  public static final org.kxg.enumDemo.OrderState ORDER_CONFIRM;  public static final org.kxg.enumDemo.OrderState ORDER_PAYED;  public static final org.kxg.enumDemo.OrderState ORDER_DELIVERY;  public static final org.kxg.enumDemo.OrderState ORDER_FINISH;  //私有变量变成类的私有变量  private int state;  private java.lang.String stateText;  private static final org.kxg.enumDemo.OrderState[] $VALUES;  //values()很有意思,它是编译器自动生成的  public static org.kxg.enumDemo.OrderState[] values();  public static org.kxg.enumDemo.OrderState valueOf(java.lang.String);  //构造方法  private org.kxg.enumDemo.OrderState(int, java.lang.String);  public int getState();  public java.lang.String getStateText();  public static void main(java.lang.String[]);  static {};}

从反编译回来的内容,可以看出来,枚举类型本质是就是继承自Enum的final类,枚举中定义的常量就是类的静态常量

有一个很有意思的点就是,编译器会自动生成values()方法,因为在枚举本身和Enum类中都没有values()方法,只能是编译器在编译的时候自动生成的

枚举可以继承,可以实现接口吗?

枚举可以继承吗?可以实现接口吗?

面试官就喜欢问类似的问题,如果你对枚举不了解,肯定就答不上来了

从上面反编译的结果来看,枚举本质是个final类并且继承自Enum,Java里面不支持多继承,所以枚举不能继承其他类,同时枚举是个final类,也不能被继承

但枚举可以实现接口,枚举本质上就是个类,所以它有类的一般特性

定义一个接口

public interface Color {    public String getColor();}

定义一个枚举类型,实现Color接口

public enum EmnuInterface implements Color {    RED("红色"),GREEN("绿色"),GRAY("灰色"),YELLOW("黄色");    private String color;    EmnuInterface(String color){        this.color = color;    }    @Override    public String getColor() {        return color;    }    public static void main(String[] args){        EmnuInterface color = EmnuInterface.GREEN;        System.out.println(color.getColor());    }}

输入结果:

绿色

枚举的优缺点

1、枚举常量简单安全

不使用枚举的时候,我们是这样定义常量的

public static final String RED = "红色";public static final String GREEN = "绿色";public static final String GRAY = "灰色";public static final String YELLOW = "黄色";

这样使用看起来也没什么问题,可以达到常量的效果,但这个静态常量是不具有范围限定的,比如我有一个方法要限定只能传入指定的几个颜色,使用静态常量就无法限制范围,使用者可以随意传入静态常量,但如果使用了枚举就可以限定只能传入指定范围内的值

2、枚举有内置方法

如果要列出所有的常量,类和接口必须使用反射,比较繁琐,而枚举有内置的方法values()可以很方便的列举出静态常量

3、枚举的缺点

枚举不可继承,无法扩展,但枚举一般用来定义常量,也不需要扩展

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值