Java根据code获取枚举优化方式

 更新时间:2026年03月02日 10:05:31   作者:丁花不是花  
文章介绍了如何优化枚举类根据code获取枚举类型的过程,通过创建基接口BaseEnum和枚举工具类MyEnumUtil,实现了通用的获取方法,同时,还讨论了根据description获取枚举的优化方法,并建议使用第二种方法

需求

自己模拟两个枚举,假设业务中需要用到

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接口即可

例如,Example1StatusEnumExample2StatusEnum都需要使用。

分别修改如下:

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 获取枚举,实际场景可能遇不到,重点在于思想。

那么几种解决方案:

  1. 原有的BaseEnum接口上加一个String getDescription(),然后MyEnumUtil 中添加一个和toEnumByCode类似的方法,泛型中依然使用BaseEnum。
  2. 新建一个接口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。

正常获取。

至此,优化完成。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java面向对象程序设计多态性示例

    Java面向对象程序设计多态性示例

    这篇文章主要介绍了Java面向对象程序设计多态性,结合实例形式分析了java多态性的概念、原理、定义与使用方法及相关注意事项,需要的朋友可以参考下
    2018-03-03
  • Spring中的@ExceptionHandler注解统一异常处理详解

    Spring中的@ExceptionHandler注解统一异常处理详解

    这篇文章主要介绍了Spring中的@ExceptionHandler注解统一异常处理详解,当我们使用这个@ExceptionHandler注解时,定义一个异常的处理方法,加上@ExceptionHandler注解,这个方法就会处理类中其他方法抛出的异常,需要的朋友可以参考下
    2024-01-01
  • Java编程实现深度优先遍历与连通分量代码示例

    Java编程实现深度优先遍历与连通分量代码示例

    这篇文章主要介绍了Java编程实现深度优先遍历与连通分量代码示例,
    2017-11-11
  • java.lang.UnsupportedOperationException分析及解决办法

    java.lang.UnsupportedOperationException分析及解决办法

    日常开发中我遇到java.lang.UnsupportedOperationException:异常两次了,下面这篇文章主要给对大家介绍了关于java.lang.UnsupportedOperationException分析及解决办法,需要的朋友可以参考下
    2024-03-03
  • SpringBoot集成easy-rules规则引擎流程详解

    SpringBoot集成easy-rules规则引擎流程详解

    这篇文章主要介绍了SpringBoot集成easy-rules规则引擎流程,合理的使用规则引擎可以极大的减少代码复杂度,提升代码可维护性。业界知名的开源规则引擎有Drools,功能丰富,但也比较庞大
    2023-03-03
  • IDEA热更新代码的两种方式详解

    IDEA热更新代码的两种方式详解

    本文详解IDEA代码热更新的两种方式:系统配置(需Ultimate版,仅支持新增修改)和插件(JRebel/XRebel,支持全面自动更新),系统需手动刷新,插件可定时自动更新但可能影响性能,需要的朋友可以参考下
    2025-08-08
  • Mybatis-plus动态条件查询QueryWrapper的使用案例

    Mybatis-plus动态条件查询QueryWrapper的使用案例

    mybatis-plus框架功能很强大,把很多功能都集成了,下面这篇文章主要给大家介绍了关于Mybatis-plus动态条件查询QueryWrapper的使用教程,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • springBoot整合CXF并实现用户名密码校验的方法

    springBoot整合CXF并实现用户名密码校验的方法

    这篇文章主要介绍了springBoot整合CXF并实现用户名密码校验的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 在Spring中自动装配Bean的属性

    在Spring中自动装配Bean的属性

    今天小编就为大家分享一篇关于在Spring中自动装配Bean的属性,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • SpringBoot整合OpenFeign的坑

    SpringBoot整合OpenFeign的坑

    最近试用SpringBoot+K8S,遇到了个坑,通过OpenFeign请求返回值LocalDateTime发生了异常,本文就详细的介绍一下解决方法,感兴趣的可以了解一下
    2021-07-07

最新评论