搜索
首页Javajava教程java为什么要使用枚举?

java为什么要使用枚举?

May 22, 2019 am 11:24 AM
java枚举

最近发现公司的代码中存在大量的使用int枚举的方式,也看到了一些使用enum进行枚举的方式。对此很好奇,进行了研究,估写此文总结,来说一说为什么要使用enum。

java为什么要使用枚举?

java为什么要使用枚举?

假设现在有两种订单类型:预订订单和非预订订单。

需求一: 方法submitOrder根据不同订单类型进行不同的处理。

需求二: 给一个对象: OrderResult设置订单类型。

下面分别用两种枚举方式来实现。

int枚举

class IntEnumExample{
private static final PRE_ORDER = 1;
private static final NOT_PRE_ORDER = 2;
public void submitOrder(int orderType, OrderResult orderResult){
    orderResult.setType(orderType);
    if(orderType == PRE_ORDER){
        do something to process preOrder
    }else if(orderType == NOT_PRE_ORDER){
        do something to process other order
    }
}
public static void main(String [] args){
    IntEnumExample example = new IntEnumExample();
    //passing wrong type to the method, however, no compile error and runtime exception here, the bug is hard to be discerned.
    example.submitOrder(3, orderResult);
}
}

从上面的例子可以看到,使用int枚举有几个缺点:

1.int枚举不做类型检查,可以给上面的submitOrder方法传入任意int值

2.代码可读性低,如果没有文档或者源码,不知道给submitOrder传递的值的意义。

不仅如此,就像我之前修改项目中sonar扫描代码发现的问题那样,很多人在使用int枚举时,并没有像上例中将int值定义成static final。如果忘记定义变量为final则int枚举的值就可以被修改,如果忘记定义变量为static,就可能出现使用这个int值时,该int值还没有被初始化好。

总之,会引起bug。

下面来看看使用enum如何做同样的事儿。

class IntEnumExample{
 private enum ORDER_TYPE {
        NOT_PRE_ORDER(1),PRE_ORDER(2);
        private final int value;
        private ORDER_TYPE(int value){
            this.value = value;
        }
    }
public void submitOrder(ORDER_TYPE orderType, OrderResult orderResult){
    orderResult.setType(orderType);
    if(orderType == ORDER_TYPE.PRE_ORDER){
        do something to process preOrder
    }else if(orderType == ORDER_TYPE.NOT_PRE_ORDER){
        do something to process other order
    }
}
public static void main(String [] args){
    IntEnumExample example = new IntEnumExample();
    //compiler will complain error here, if argument is not the type in the enum.
    example.submitOrder(ORDER_TYPE.PRE_ORDER, orderResult);
}
}

通过上述代码可以看到,enum很优雅的解决了上一个例子中的问题。

1.编译器将对enum进行类型检查,类型不符合的编译器会直接报错。

2.相比与int枚举型直接传int数值的方式,enum传递enum类型对象的方式,代码可读性更高,传递的枚举类型一目了然。

3.enum类型中的对象本身就是static final的。

重要提示:

还有一点值得一提的是,如果有时想给每一个枚举类型赋予一个int值,要使用上例中enum定义的方式。

private enum ORDER_TYPE {
       NOT_PRE_ORDER(1),PRE_ORDER(2);
       private final int value;
       private ORDER_TYPE(int value){
           this.value = value;
       }
   }

enum本质也是一个类,所以方法ORDER_TYPE(int value)是这个枚举类型的构造函数,故每个枚举类型在初始化的时候需要给构造函数传递响应的值,如: PRE_ORDER(2)。

这种情况下,想得到枚举类型对应的int数值时可以通过ORDER_TYPE.PRE_ORDER.value获取。

单独提下enum的这种用法是因为,有些人可能会直接使用enum中的ordinal()方法直接实现enum类型与int类型的关联。ordinal()方法返回的是enum类型在被定义时的序数,如ORDER_TYPE.PRE_ORDER.value.ordinal()返回值为0。所以获取枚举类型对应的int数值貌似也可以通过ORDER_TYPE.PRE_ORDER.value.ordinal()+1实现。

不要使用ordinal()方法!不要使用ordinal()方法!不要使用ordinal()方法!重要的事情说三遍,为什么?

序数是很不可靠的东西,序数是可以改变的,假设有一天ORDER_TYPE的定义变了,需要增加几种类型,或者不小心换了NOT_PRE_ORDER和PRE_ORDER定义时的顺序,如:

private enum ORDER_TYPE {
       PRE_ORDER,NOT_PRE_ORDER;
   }

这时就会造成很严重的bug,而且不好发现,编译时,运行时都不会有报错。

所以,不要依赖ordianl()方法。

相关学习推荐:java基础教程

以上是java为什么要使用枚举?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境