需求
自己模拟两个枚举,假设业务中需要用到
example1statusenum.java
package com.zdh.zdhenum;
/**
* @author dh
* @date 2024/07/24
* @desc (详细信息)
*/
public enum example1statusenum {
new("new", "新建状态"),
fail("fail", "失败状态"),
success("success", "成功状态"),
closed("closed", "关闭状态");
private string code;
private string description;
example1statusenum(string code, string description) {
this.code = code;
this.description = description;
}
}
example2statusenum .java
package com.zdh.zdhenum;
import com.fasterxml.jackson.databind.ser.serializers;
/**
* @author dh
* @date 2024/07/24
* @desc (详细信息)
*/
public enum example2statusenum implements baseenum {
new("new", "新建状态"),
fail("fail", "失败状态"),
success("success", "成功状态"),
processing("processing", "处理中状态"),
waiting("waiting", "等待状态"),
closed("closed", "关闭状态"),
abandoned("abandoned", "弃状态");
private string code;
private string description;
example2statusenum(string code, string description) {
this.code = code;
this.description = description;
}
}
实际场景中,可能远远大于2个,每个枚举类内item有唯一的code,实际业务开发中需要根据唯一的code获取对应的枚举类型。
原始解决方案
哪个枚举类需要根据code获取对应的枚举,就在该枚举类中添加获取方法
例如example1statusenum 需要根据code获取对应的枚举,在example1statusenum 添加如下方法:
public static example1statusenum toenum(string code){
for (example1statusenum item : example1statusenum.values()) {
if (objects.equals(item.getcode(),code)) {
return item;
}
}
return null;
}
同理,其他需要用到此方法,都需要复制上面的方法,并更改为对应类型,大量重复性工作。
优化方案
1. 首先创建base接口。
package com.zdh.zdhenum;
/**
* @author dh
* @date 2024/07/23
* @desc (详细信息)
*/
public interface baseenum {
/**
* 获取code
* @return
*/
string getcode();
}
后面工具类根据此接口方法可以 通用的获取code
2. 创建枚举工具类
package com.zdh.zdhenum;
import java.util.objects;
/**
* @author dh
* @date 2024/07/24
* @desc (详细信息)
*/
public class myenumutil {
public static <e extends enum<e> & baseenum> e toenumbycode(string code, class<e> enumclass) {
for (e enumconstant : enumclass.getenumconstants()) {
if (objects.equals(enumconstant.getcode(),code)) {
return enumconstant;
}
}
return null;
}
}
<e extends enum<e> & baseenum> 这里泛型,extends 表现必须继承自后面的xxx,baseenum规定必须实现上面定义的baseenum接口,enum<e> 为枚举类的公共父类,规定必须是枚举类可以用此方法。
3. 需要使用工具类的枚举,实现baseenum接口即可
例如,example1statusenum 和example2statusenum都需要使用。
分别修改如下:
package com.zdh.zdhenum;
import java.util.objects;
/**
* @author dh
* @date 2024/07/24
* @desc (详细信息)
*/
public enum example1statusenum implements baseenum{
new("new", "新建状态"),
fail("fail", "失败状态"),
success("success", "成功状态"),
closed("closed", "关闭状态");
private string code;
private string description;
example1statusenum(string code, string description) {
this.code = code;
this.description = description;
}
/**
* 获取code
*
* @return
*/
@override
public string getcode() {
return this.code;
}
}
package com.zdh.zdhenum;
import com.fasterxml.jackson.databind.ser.serializers;
/**
* @author dh
* @date 2024/07/24
* @desc (详细信息)
*/
public enum example2statusenum implements baseenum {
new("new", "新建状态"),
fail("fail", "失败状态"),
success("success", "成功状态"),
processing("processing", "处理中状态"),
waiting("waiting", "等待状态"),
closed("closed", "关闭状态"),
abandoned("abandoned", "弃状态");
private string code;
private string description;
example2statusenum(string code, string description) {
this.code = code;
this.description = description;
}
/**
* 获取code
*
* @return
*/
@override
public string getcode() {
return this.code;
}
}
4. 测试使用
public static void main(string[] args) {
example1statusenum quotastatusenum11 = myenumutil.toenumbycode("new", example1statusenum.class);
system.out.println("quotastatusenum11 = " + quotastatusenum11);
example1statusenum quotastatusenum12 = myenumutil.toenumbycode("fda", example1statusenum.class);
system.out.println("quotastatusenum12 = " + quotastatusenum12);
example2statusenum quotastatusenum21 = myenumutil.toenumbycode("new", example2statusenum.class);
system.out.println("quotastatusenum11 = " + quotastatusenum21);
example2statusenum quotastatusenum22 = myenumutil.toenumbycode("fda", example2statusenum.class);
system.out.println("quotastatusenum12 = " + quotastatusenum22);
}
为了方便查看效果,可以在最后打个断点。

查看结果,发现和预期一样

拓展
假设,可能需要根据description 获取枚举,实际场景可能遇不到,重点在于思想。
那么几种解决方案:
- 在原有的baseenum接口上加一个string getdescription(),然后myenumutil 中添加一个和toenumbycode类似的方法,泛型中依然使用baseenum。
- 新建一个新接口basedescenum,里面就一个string getdescription()方法。然后myenumutil 中添加一个和toenumbycode类似的方法,泛型中使用新的basedescenum。
这里我建议使用第2种方法,这样颗粒度更细。第1种就算不需要根据description 获取枚举,也要实现string getdescription方法(虽然1.8之后可以通default关键字在接口默认实现,但是个人不太建议此场景这么使用)。
下面简单说一下实现。
新增basedescenum接口
package com.zdh.zdhenum;
/**
* @author dh
* @date 2024/07/23
* @desc (详细信息)
*/
public interface basedescenum {
/**
* 获取description
* @return
*/
string getdescription();
}
假设仅仅example1statusenum需要,代码修改如下:
package com.zdh.zdhenum;
import java.util.objects;
/**
* @author developer_zhangxinhua
* @date 2024/07/24
* @desc (详细信息)
*/
public enum example1statusenum implements baseenum,basedescenum{
new("new", "新建状态"),
fail("fail", "失败状态"),
success("success", "成功状态"),
closed("closed", "关闭状态");
private string code;
private string description;
example1statusenum(string code, string description) {
this.code = code;
this.description = description;
}
/**
* 获取code
*
* @return
*/
@override
public string getcode() {
return this.code;
}
/**
* 获取description
*
* @return
*/
@override
public string getdescription() {
return this.description;
}
}
myenumutil中添加如下方法
public static <e extends enum<e> & basedescenum> e toenumbydesc(string desc, class<e> enumclass) {
for (e enumconstant : enumclass.getenumconstants()) {
if (objects.equals(enumconstant.getdescription(),code)) {
return enumconstant;
}
}
return null;
}
调用
public static void main(string[] args) {
example1statusenum quotastatusenum11 = myenumutil.toenumbycode("new", example1statusenum.class);
system.out.println("quotastatusenum11 = " + quotastatusenum11);
example1statusenum quotastatusenum12 = myenumutil.toenumbycode("processing", example1statusenum.class);
system.out.println("quotastatusenum12 = " + quotastatusenum12);
example2statusenum quotastatusenum21 = myenumutil.toenumbycode("processing", example2statusenum.class);
system.out.println("quotastatusenum11 = " + quotastatusenum21);
example2statusenum quotastatusenum22 = myenumutil.toenumbycode("fda", example2statusenum.class);
system.out.println("quotastatusenum12 = " + quotastatusenum22);
example1statusenum enumbydesc11 = myenumutil.toenumbydesc("新建状态", example1statusenum.class);
system.out.println("enumbydesc11 = " + enumbydesc11);
example1statusenum enumbydesc12 = myenumutil.toenumbydesc("xfdas", example1statusenum.class);
system.out.println("enumbydesc12 = " + enumbydesc12);
// example1statusenum enumbydesc13 = myenumutil.toenumbydesc("新建状态", example2statusenum.class);
// system.out.println("enumbydesc13 = " + enumbydesc13);
}
发现如果example2statusenum没有实现basedescenum,连编译都不能通过。为什么上文不建议使用default,这样如果别人不熟悉实现,使用我们的工具类,可以强制让使用该工具类的人员,必须通过basedescenum实现进行重写getdescription,防止忘记重写getdescription,从而获取到错误的description。

正常获取。

至此,优化完成。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论