话不多少抛问题:
我定义enum :
@AllArgsConstructor
@NoArgsConstructor
@Getter
public enum ValidationExceptionCodeEnums {
SCOOTERID_IS_EMPTY(1001, "scooterId 为空"),
EVENT_IS_EMPTY(1002, "事件 为空"),
LONGITUDE_IS_EMPTY(1003, "经度为空"),
LATITUDE_IS_EMPTY(1004, "维度为空"),
ACTION_RESULT_IS_EMPTY(1005, "Action 结果为空"),
GEOHASH_IS_EMPTY(1006, "geohash为空"),
BATTERY_IS_EMPTY(1007, "电量为空"),
BEGINTIME_IS_EMPTY(1008, "开始时间为空"),
ENDTIME_IS_EMPTY(1009, "结束时间为空"),
DESTINATION_IS_NOT_EMPTY(1010, "目的地为空"),
DESTINATION_LATITUDE_IS_NOT_EMPTY(1011, "目的地经度为空"),
DESTINATION_LONGITUDE_IS_NOT_EMPTY(1012, "目的地 维度为空"),
SCOOTER_STATUS_IS_EMPTY(1013, "scooter 状态为空"),
REPAIR_TYPE_IS_EMPTY(1014, "维修类型为空"),
BOOKTIME_IS_EMPTY(1015, "预约时间为空"),
REPAIT_SCOOTER_STATUS_IS_EMPTY(1016, "维修sooter的状态为空"),
SCOOTER_LICENSE_IS_EMPTY(1017, "车牌号为空"),
SCOOTER_LICENSE_PICTURE_IS_EMPTY(1018, "车牌号图为空"),
SCOOTER_LICENSE_TIME_IS_EMPTY(1019, "上牌时间为空")
;
private int code;
private String message;
public static ValidationExceptionCodeEnums getErrorCodeByCode(int code) {
for (ValidationExceptionCodeEnums item : ValidationExceptionCodeEnums.values()) {
if (item.getCode() == code) {
return item;
}
}
return null;
}
}
对入参对象进行参数过滤:
提示我 必须是常量!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
大佬们 有没有更好的解决方案 , 规避掉。
找到如下原因:
上回书说enum类型天生是final和static的。Java中的常量,我们知道也一般定义为static final。例如:
1 | private static final int intConstant = 1; |
上面这行代码中,变量intConstant
就是一个常量,常量意味着intConstant
的值在编译时就能够确定,并且无法改变。
这样听起来被定义为static final
的变量就能称之为常量了啊,enum天生就是static final
的,enum天生就是常量啦?
答案是,不一定哦~
发现问题
今天在使用mybatis写一个dao, 像之前每天做的工作一样,写一个简单的select语句。写的select语句中where子句中有个判断字段status,这个字段被定义为int,每一个int值对应一个状态。在以前,我会这样写这个sql语句。
1 2 | @Select(Select column1, column2 from sample_table where status = 1 or status =2) public List<SampleTable> getSampleData(); |
现在,我慢慢学会使用enum了,于是我打算把status的状态用enum来表示。于是我开始这样写代码。
1 2 3 4 5 6 7 8 9 | private enum SAMPLE_STATUS{ STATUS1(1), STATUS2(2); private int value; private SAMPLE_STATUS(int value){ this.value = value }; } @Select(Select column1, column2 from sample_table where status = SAMPLE_STATUS.STATUS1.value or status =SAMPLE_STATUS.STATUS2.value) public List<SampleTable> getSampleData(); |
可是,我这样写代码后@Select
那行编译器报错: “attribute value must be constant“.
为什么啊,enum不是static final
的吗?不应该是常量吗?为什么提示我说这个属性必须是常量呢?
分析问题
出现了这样的错误,我很好奇。重新看了下自己的代码,并进行了一番谷歌之后,我突然醒悟了。我tm太傻逼了。
真相应该是enum是天生static final
没错,所以SAMPLE_STATUS.STATUS1是常量,但是,SAMPLE_STATUS.STATUS1对应的这个值就不一定是了。因为这个int值是在enum的构造器中初始化的,也就是说,SAMPLE_STATUS.STATUS1对应的int值,应该是在enum类被加载的时候才被赋值,编译时还没有被赋值。
为了验证我的想法,我写了下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private enum Fruit{ Strawberry(1), Banana(2), Kiwi(3); private int value; private Fruit(int value){ System.out.println("The value is " + value); this.value = value; } } public static void main(String [] args) { int value = Fruit.Strawberry.value; System.out.println("The value of strawberry is " + value); Fruit.Strawberry.setValue(3); System.out.print("The value of strawberry is " + value); } |
上面的代码运行的结果是:
1 2 3 4 5 | The value is 1 The value is 2 The value is 3 The value of strawberry is 1 The value of strawberry is 1 |
前三行输出结果说明,当enum类加载的时候,会依次调用构造器,生成不同的枚举类实例,实例对应的int值也依次被初始化。
后两行输出结果说明,被初始化后的int值也是final的,不可被修改,尽管我调用了setValue
方法,试图改变其int的值。
解决问题
既然enum对应的int值不是常量,我还是想用enum类型去表示我的sql语句中的status字段的值,咋办呢?
1 2 3 4 5 6 7 8 9 | @SelectProvider(type = Provider.class, method = "getSampleData") public List<SampleTable> getSampleData(); public static class Provider { public static String getSampleData(){ return "Select column1, column2 from sample_table where status =" + SAMPLE_STATUS.STATUS1.value + "or status =" + SAMPLE_STATUS.STATUS2.value; } } |
注解中要求所有的值必须是常量,但是class中没有这样的要求。
所以,使用Provider可以完美的解决这个问题。
来自:原贴