java 枚举类
是什么?为什么使用枚举类?
一、是什么
枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。
1 2 3 4 5 6 7 8 9 10 11 |
enum Status { NotFound(404), ServerError(500), NoAuth(503); private int code; private Status(int code) { this.code = code; } } |
二、为什么使用枚举类?
(1)举个错误的例子
记得刚开始写spring mvc时,每次返回json都需要return一个returnPojo对象。
我当时是这样做的:
1 2 3 4 5 6 7 |
returnPojo returnPojo = new returnPojo(); returnPojo.setRetCode(200); returnPojo.setRetData(map); returnPojo.setRetMsg("查询成功"); return returnPojo; |
我每次都是直接返回一个状态码(比如请求成功,就set一个200),加上请求的数据data,再加上返回的信息(比如请求成功,就set一个“查询成功”)。
一开始,我感觉这种做法毫无问题,但是后来我就懵逼了。
1.别人怎么知道你这个200是什么意思?
这个200是我自己定义的,因为整个项目都是我在开发,所以理解起来没有难度。如果别人接手了这个项目,那他就要想办法猜测这个200的意思。
2.如何修改RetCode?
假设别人清楚200代表“请求成功”,那现在我要修改一下RetCode(比如改成100200代表“请求成功”),怎么修改呢?
我是不是要找到每一个returnPojo对象,一个个把200改成100200?如果项目中存在大量的returnPojo,可能要找到天荒地老。
同理,如果我要修改RetMsg,也会非常麻烦。
(2)为了解决上面的问题,我使用了静态常量类
Main.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.test.testEnum; import com.test.testEnum.ConstVal; public class Main { public static void main(String[] args) { ReturnPojo returnPojo = new ReturnPojo(); returnPojo.setRetCode(ConstVal.SUCCESS_CODE); } } class ConstVal { public static final int SUCCESS_CODE = 200; public static final int FAIL_CODE = 500; } |
“SUCCESS_CODE”的含义比“200”更加清楚。“200”要猜测,“SUCCESS_CODE”一看就知道是“请求成功时返回的状态码”。
如果要修改状态码,直接修改静态常量类就好,不用到处去找RetCode。
这样做确实能解决问题,个人认为挺好用,实现效果和“枚举类”没有太大的区别。
(我看见很多人毫无理由地推崇“枚举类”,感觉有点莫名其妙)。
(3)使用枚举类
实现大概是这样:
Main.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.test.testEnum; public class TestEnum { public static void main(String[] args) { ReturnPojo returnPojo = new ReturnPojo(); returnPojo.setRetCode(Status.NotFound.getCode()); } } enum Status { NotFound(404), ServerError(500), NoAuth(503); private int code; private Status(int code) { this.code = code; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } } |
这样也是可行的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.test.testEnum; public class TestEnum { public static void main(String[] args) { ReturnPojo returnPojo = new ReturnPojo(); returnPojo.setRetCode(Status.NotFound.val); } } enum Status { NotFound(404), ServerError(500), NoAuth(503); final int val; private Status(int val) { this.val = val; } } |
要说这种方式有独特的优势,我也没怎么感觉…..
三、更多的用法
参考:http://blog.csdn.net/u012403290/article/details/70052450
(1)配合switch(具有一定能力的枚举)
TestEnum.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.test.testEnum; public class TestEnum { public static void main(String[] args) { ReturnPojo returnPojo = new ReturnPojo(); returnPojo.setRetCode(Status.NotFound.GetCode()); } } enum Status { NotFound, ServerError, NoAuth; Integer GetCode() { switch (this) { case NotFound: return 404; case ServerError: return 500; case NoAuth: return 503; default: return 0; } } } |
(2)配合抽象方法(特定于常量的方法实现)
TestEnum.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package com.test.testEnum; public class TestEnum { public static void main(String[] args) { ReturnPojo returnPojo = new ReturnPojo(); returnPojo.setRetCode(Status.NotFound.GetCode()); } } enum Status { NotFound { @Override int GetCode() { // TODO Auto-generated method stub return 404; } }, ServerError { @Override int GetCode() { // TODO Auto-generated method stub return 500; } }, NoAuth { @Override int GetCode() { // TODO Auto-generated method stub return 503; } }; abstract int GetCode(); } |
把GetCode()设定为抽象方法。每当你定义一个枚举常量,就会被强制要求你实现这个方法。这种方式被称为“特定于常量的方法实现”,可以防止“新增一个常量后忘记添加特定属性”的情况。
(3)枚举里面嵌套枚举(策略枚举)
我暂时还没有搞懂为什么要这样写。
TestEnum.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
package com.test.testEnum; public class TestEnum { public static void main(String[] args) { ReturnPojo returnPojo = new ReturnPojo(); returnPojo.setRetCode(Code.Status.NotFound.GetCode()); } } enum Code { NotFound(Status.NotFound), ServerError(Status.ServerError), NoAuth(Status.NoAuth); private Code(Status status) { // 作用是强制code枚举类选择一个状态Status?搞不明白..... } enum Status { NotFound { @Override int GetCode() { // TODO Auto-generated method stub return 404; } }, ServerError { @Override int GetCode() { // TODO Auto-generated method stub return 500; } }, NoAuth { @Override int GetCode() { // TODO Auto-generated method stub return 503; } }; abstract int GetCode(); } } |
感觉有点莫名其妙。
三、总结
枚举类我用得太少了。用是会用,但是不知道哪里适合用枚举类…..