【工具类】比较优雅的在工具类中,用泛型方法获取枚举的值

痛点

在代码中,经常用到枚举,也经常用到枚举获取code,获取type,通常我们写的代码如下:

 public  enum Status{
    /**
     *
     */
    YES(1,"是"),
    NO(2,"否")

    ;
    private int code;
    private String msg;

    Status(int code, String msg) {
      this.code = code;
      this.msg = msg;
    }


    public int getCode() {
      return this.code;
    }


    public String getMsg() {
      return this.msg;
    }

    public static Optional<Status> of(int code) {
      for (Status value : values()) {
         if (Objects.equals(value.getCode(),code)){
          return Optional.of(value);
        }
      }
      return Optional.empty();
    }


  }

要根据某个code,得到枚举以及对应的msg,调用of()方法。但是这样的话每个枚举都得写一边,代码行数还不少。不简洁

一开始的优化,就是写了个接口如下:

public interface IEntityEnum {

 public int getCode();

 public String getMsg();

}

然后枚举实现这个接口,相当于一个标准能保证枚举类都能有这样的of方法可以用。但是实际问题还是没解决,代码在每个枚举都要复制。

解决

其实这个也不难想,把这些of方法通通抽取出去在一个工具类中,采用泛型来匹配各种枚举类,但是问题在于,怎么调用values方法呢?怎么告诉编译器我这个方法需要的是一个枚举,我要调用它的values方法,毕竟其他类又没这个静态方法。直到我无意发现了getEnumConstants方法,它是Object类里的。
它的介绍:

an array containing the values comprising the enum class represented by this Class object in the order they’re declared, or null if this Class object does not represent an enum type

一个数组,其中包含组成此 Class 对象表示的枚举类的值,按声明的顺序排列;如果此 Class 对象不表示枚举类型,则为 null

因此工具类就好写了:


import cn.hutool.core.util.StrUtil;
import java.util.Optional;

/**
 * EnumsUtil
 *
 * @author zgd
 * @date 2022/8/9 17:44
 */
public class EnumsUtil {

    public static <T extends IEntityEnum> Optional<T> of(int code, Class<T>  cla) {
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (code == value.getCode()){
                return Optional.of(value);
            }
        }
        return Optional.empty();
    }



    public static <T extends IEntityEnum> String ofMsg(int code, Class<T>  cla) {
        Optional<T> of = of(code,cla);
        return of.isPresent() ? of.get().getMsg() : "";
    }

    public static <T extends IEntityEnum> Integer ofCode(String msg, Class<T>  cla) {
        if (StrUtil.isEmpty(msg)){
            return null;
        }
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (msg.equals(value.getMsg())){
                return value.getCode();
            }
        }
        return null;
    }
/**
* 可以试下效果
*/
    public static void main(String[] args) {
        System.out.println(EnumsUtil.ofMsg(1, SourceEnum.class));
        System.out.println(EnumsUtil.ofMsg(2, SourceEnum.class));
    }
}


优化更灵活的泛型

用了一天后发现一个问题, 接口IEntityEnum写死了int code和String msg, 那如果有时候code我们需要String类型,这个场景也很常见.
因此再往上包装一层

  • 增加一个接口

/**
 * IEnum
 *
 * @author zgd
 * @date 2022/8/10 18:09
 */
public interface IEnum<T,E> {

    public T getCode();

    public E getMsg();

}

  • 继承这个接口,这个用的比较多,作为一个默认的子接口
public interface IEntityEnum extends IEnum<Integer,String> {

 public Integer getCode();

 public String getMsg();

}


import cn.hutool.core.util.StrUtil;

import java.util.Optional;

/**
 * EnumsUtil
 *
 * @author zgd
 * @date 2022/8/9 17:44
 */
public class EnumsUtil {

    public static  <E,V,T extends IEnum<E,V>>  Optional<T> of(E code, Class<T>  cla) {
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (code == value.getCode()){
                return Optional.of(value);
            }
        }
        return Optional.empty();
    }



    public static <E,V,T extends IEnum<E,V>> V ofMsg(E code, Class<T>  cla) {
        Optional<T> of = of(code,cla);
        return of.map(IEnum::getMsg).orElse(null);
    }

    public static <E,V,T extends IEnum<E,V>> E ofCode(String msg, Class<T>  cla) {
        if (StrUtil.isEmpty(msg)){
            return null;
        }
        T[] enums = cla.getEnumConstants();
        for (T value : enums) {
            if (msg.equals(value.getMsg())){
                return value.getCode();
            }
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(EnumsUtil.ofMsg("YES", TypeEnum.class));
    }
}
  • 如果我们需要一个code是String类型的,不实现IEntityEnum,直接实现它的父接口
  /**
     * TypeEnum
     *
     * @author zgd
     * @date 2022/8/10 18:41
     */
    public enum TypeEnum implements IEnum<String,String> {

        /**
         *
        */
        YES("YES","是"),
        NO("NO","否"),

        ;

        private String code;
        private String msg;

        TypeEnum(String code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        @Override
        public String getCode() {
            return this.code;
        }

        @Override
        public String getMsg() {
            return this.msg;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值