背景
最近修改項目的時候發現一些好東西,對於枚舉的通用方法的處理,發現之前寫的很多重複性的勞動,總體來說對於枚舉的認識不夠,對於這些特性的使用還不是非常的屬性,編碼這個東西,總在反思、學習中成長,這種小東西也是一種成長,別看微不足道,大規模推廣使用起來,對於編碼的統一度非常的友好的。
實踐
幾乎在系統的枚舉中都是code、msg這樣的枚舉,非常的多!沒有直接的利用Enum中的name,主要是語法糖抽象的後果,看不到這個字段,很少用。一般都是通過code 獲取到枚舉,通過code 判斷是否存在個枚舉,通過code 獲取到msg … 我相信你也寫了不少的這樣的東西
反例
看起來無傷大雅,基本都能夠讀懂,但是一個系統中有很多這樣的枚舉,每個都寫一遍,你會發現非常的傷不起。但是我也寫過…
package com.wangji92.github.study.other.enums;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* 任務狀態枚舉
*
* @author 汪小哥
* @date 09-03-2020
*/
@Slf4j
public enum TaskStatusEnum {
SUCCESS("success", "成功"),
FAIL("fail", "失敗"),
CANCEL("cancel", "取消");
/**
* 編碼表示
*/
private String code;
/**
* 說明
*/
private String msg;
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
TaskStatusEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
private static Map<String, TaskStatusEnum> taskMaps = new HashMap<>();
static {
for (TaskStatusEnum value : TaskStatusEnum.values()) {
taskMaps.put(value.getCode(), value);
}
}
public static String getMsgByCode(String code) {
TaskStatusEnum taskStatusEnum = getEnumByCode(code);
String msg = taskStatusEnum != null ? taskStatusEnum.getMsg() : "";
return msg;
}
public static TaskStatusEnum getEnumByCode(String code) {
return taskMaps.get(code);
}
public static void main(String[] args) {
String success = TaskStatusEnum.getMsgByCode("success");
log.info("msg:" + success);
boolean validEnumCode = TaskStatusEnum.getEnumByCode("success") != null;
log.info("validEnumCode:" + validEnumCode);
}
}
正例
繼承關係圖
實現類
enum 這個是一個語法糖,所有的都繼承了java.lang.Enum,Java不支持多繼承,只能通過接口處理咯,一個是code 一個是msg。如下所示,有區別?都是一樣的而且這裏的很多的方法都沒有啦
package com.wangji92.github.study.other.enums.enhance;
import java.io.Serializable;
/**
* @author 汪小哥
* @date 09-03-2020
*/
public interface EnumCode<T> extends Serializable {
/**
* 獲取枚舉的返回Code
*
* @param <T>
* @return
*/
T getCode();
}
/**
* 枚舉的返回msg的信息
*
* @author 汪小哥
* @date 09-03-2020
*/
public interface EnumCodeMsg<T> extends EnumCode<T> {
/**
* 獲取枚舉的備註信息
* @return
*/
String getEnumMsg();
}
/**
* @author 汪小哥
* @date 09-03-2020
*/
@Slf4j
public enum TaskStatusEnumsTwo implements EnumCodeMsg<String> {
SUCCESS("success", "成功"),
FAIL("fail", "失敗"),
CANCEL("cancel", "取消");
private String code;
private String msg;
TaskStatusEnumsTwo(String code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public String getEnumMsg() {
return msg;
}
@Override
public String getCode() {
return code;
}
}
EnumCodeMsgUtils 工具類
這裏可以添加繼承 org.apache.commons.lang3.EnumUtils 要不要都可以~
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
enumClass.getEnumConstants 就是獲取語法糖中的values的方法
package com.wangji92.github.study.other.enums.enhance;
import org.apache.commons.lang3.EnumUtils;
import java.util.Objects;
import java.util.Optional;
/**
* 枚舉處理工具類
*
* @author 汪小哥
* @date 09-03-2020
*/
public class EnumCodeMsgUtils extends EnumUtils {
/**
* 根據code 獲取到當前的枚舉
*
* @param enumClass
* @param code
* @param <E>
* @param <T>
* @return
*/
public static <E extends Enum<E> & EnumCodeMsg<T>, T> Optional<E> getEnumByCode(Class<E> enumClass, T code) {
if (code == null) {
return Optional.empty();
}
for (E enumConstant : enumClass.getEnumConstants()) {
if (Objects.equals(enumConstant.getCode(), code)) {
return Optional.of(enumConstant);
}
}
return Optional.empty();
}
/**
* 根據code 獲取到枚舉的msg的信息
*
* @param enumClass
* @param code
* @param defaultMsg 默認返回值
* @param <E>
* @param <T>
* @return
*/
public static <E extends Enum<E> & EnumCodeMsg<T>, T> String getEnumMsgByCode(Class<E> enumClass, T code, String defaultMsg) {
Optional<E> enumByCode = EnumCodeMsgUtils.getEnumByCode(enumClass, code);
if (enumByCode.isPresent()) {
return enumByCode.get().getEnumMsg();
}
return defaultMsg;
}
/**
* 根據code 獲取到枚舉的msg的信息,默認返回爲空
* @param enumClass
* @param code
* @param <E>
* @param <T>
* @return
*/
public static <E extends Enum<E> & EnumCodeMsg<T>, T> String getEnumMsgByCode(Class<E> enumClass, T code) {
return EnumCodeMsgUtils.getEnumMsgByCode(enumClass,code,"");
}
/**
* 這個是否是一個有效的code
*
* @param enumClass
* @param code
* @param <E>
* @param <T>
* @return
*/
public static <E extends Enum<E> & EnumCodeMsg<T>, T> boolean isValidEnumCode(Class<E> enumClass, T code) {
Optional<E> enumByCode = EnumCodeMsgUtils.getEnumByCode(enumClass, code);
return enumByCode.isPresent();
}
}
demo
public static void main(String[] args) {
//獲取msg
String success = EnumCodeMsgUtils.getEnumMsgByCode(TaskStatusEnumsTwo.class, "success", "");
log.info("msg:"+success);
//獲取是否存在
boolean validEnumCode = EnumCodeMsgUtils.isValidEnumCode(TaskStatusEnumsTwo.class, "success");
log.info("validEnumCode:"+validEnumCode);
//獲取msg的信息
Optional<TaskStatusEnumsTwo> codeEnum = EnumCodeMsgUtils.getEnumByCode(TaskStatusEnumsTwo.class, "success");
codeEnum.ifPresent(taskStatusEnumsTwo -> log.info("getEnumByCode:" + taskStatusEnumsTwo.getCode() + taskStatusEnumsTwo.getEnumMsg()));
}
參考文檔
- java枚舉工具類
- 深入理解Java枚舉類型(enum)
- Enum 枚舉小記- by 汪小哥
總結
有上面的方法,如果大規模的使用,對於枚舉來說進行了規範,所有的都一樣這樣對於自己開發來說十分的優好的。不斷的總結、才能不斷提高自己的編碼水平;理論和實踐一樣重要。
更多汪小哥