如何优雅的使用枚举

沙海
沙海
沙海
1017
文章
2
评论
2021年4月20日05:53:40
评论
1 4158字阅读13分51秒
摘要

速读摘要

速读摘要

这些信息在数据库中会以某种标识符进行保存,但是这些标识符在代码中如何呈现,每个开发者都有一套自己的习惯,这种个性化习惯在大型项目开发时可能会因代码规范问题导致严重bug,笔者阐述下在开发过程中的解决思路,使得代码更加具有可读性,请大家参考。相信学习java时就会重点说明,但是不巧,开发中我也见过有这种写法。例如如上定义,通过表明+Enum定义java类名,类中通过枚举对应到数据库的字段,这样可以在多人开发时避免出现状态码定位不一致问题,从而使得代码有一个良好的可读性。

原文约 1941 | 图片 3 | 建议阅读 4 分钟 | 评价反馈

如何优雅的使用枚举

小哈学Java

点击上方蓝色“小哈学Java”,选择“设为星标”回复“资源”获取独家整理的学习资料!

作者:叁滴水

blog.csdn.net/qq_30285985/article/details/112849366

前言

项目开发中,常有一些标识的使用,<男,女>、<正常,删除>等等。这些信息在数据库中会以某种标识符进行保存,但是这些标识符在代码中如何呈现,每个开发者都有一套自己的习惯,这种个性化习惯在大型项目开发时可能会因代码规范问题导致严重bug,在此,笔者阐述下在开发过程中的解决思路,使得代码更加具有可读性,请大家参考。

一、常见写法弊端展示

1.1、字符串匹配

在开发时将<男,女>转换为<1,2>,然后在项目组开发时互相转达这样的对应关系,就出现了如下代码。

 //如果sex是字符串,java中可以通过==对比值吗? if(user.getSex () == "1"){     //todo 如果是男生 } //Sex 是字符串类型eq方法中传入1会返回true吗? if(user.getSex ().equals (1)){      //todo 如果是男生 }

如上代码的弊端如下:

  1. user一定是对象一定是被实例化后的吗?如果user是null的话,直接使用会报空指针异常。

  2. 字符串直接==比对不是比对的Value。相信学习java时就会重点说明,但是不巧,开发中我也见过有这种写法。

  3. 字符串通过eq方法比对值一般是没有问题的,但是字符串类型的eq方法里传入的是一个Object类型的值,因此,即使传入一个数值类型也不会编译错误。如果误写成“1”.equals(1)将永远返回false。因此这种不容易发现的问题,常常导致严重的bug。

    public static void main (String[] args)    {        String man = "1";        Integer sex = 1;        System.out.println (man.equals (sex));        //输出        //false    }

另外,项目中直接通过字符串匹配,代码的可读性也会变差。多人开发的时候又有谁能够保证你说的状态1(String)和我说的状态1(Integer)是同一个1呢。

1.2、数值匹配

上面列举了字符串匹配,数值匹配同样也有容易出问题的写法。

public static void main (String[] args){    Integer man = 200;    Integer sex = 200;    System.out.println (man==sex);    Integer man1 = 2;    Integer sex1 = 2;    System.out.println (man1==sex1);}// false// true

如上这种相同的写法,却有不同的返回值,这种就很诡异。原因就在Integer.valueOf方法中。

public static Integer valueOf(int i) {    //low = -128    // high = 127    if (i >= IntegerCache.low && i <= IntegerCache.high)        return IntegerCache.cache[i + (-IntegerCache.low)];    return new Integer(i);}

因此,当比对的数值在[-128,127]的范围中,通过==对比会返回true,否则返回false,所以如果调用接口时,返回的状态码是数值型的200的时候,判断就需要注意一下。

另外,Integer也有eq方法,与String类型一样,传入Object类型,Integer.equals("1")也不会编译报错。搜索公众号Java知音,回复“2021”,送你一份Java面试题宝典)

二、代码优化

2.1、枚举对应数据库字段

例如如上定义,通过表明+Enum定义java类名,类中通过枚举对应到数据库的字段,这样可以在多人开发时避免出现状态码定位不一致问题,从而使得代码有一个良好的可读性。

import lombok.AllArgsConstructor;import lombok.Getter;import java.util.HashMap;public class UserEnum{ @Getter @AllArgsConstructor public enum Sex{  Man(1,"男"),WOMAN(2,"女");  public Integer code;  public String msg;  private static HashMap<Integer,Sex> data = new HashMap<Integer,Sex>();  static {   for(Sex d : Sex.values()){    data.put(d.code, d);   }  }  public static Sex parse(Integer code) {   if(data.containsKey(code)){    return data.get(code);   }   return null;  } } //按照如上写法,同样可以有 状态码:正常,禁用,删除 //public enum Status // 角色:管理员,普通用户 //public enum role}

2.2、数值转换枚举

在开发接口给前端开发时,前端会传入数值类型的状态,这时需要与对应的枚举类型进行转换。

代码如下:

 public static void main (String[] args) {  //此处假如客户端传入状态码 1  Integer man =1;  UserEnum.Sex parse = UserEnum.Sex.parse (man);  System.out.println (parse); }

2.3、枚举使用switch

 public static void main (String[] args) {  //此处假如客户端传入状态码 1  Integer man =1;  UserEnum.Sex parse = UserEnum.Sex.parse (man);  switch (parse){   case  Man:    //todo    break;   case WOMAN:    //todo    break;  } }

2.4、枚举状态机

虽然常有项目组通过常量来使得代码更加规范,但是通过枚举可以在多状态转换的场景下使得代码更加友好的呈现。

在一个请假单的审批过程中肯定有这几种状态<发起审批,组长审批,经理审批,人事备案>。状态机代码示例:

import lombok.AllArgsConstructor;import lombok.Getter;@Getter@AllArgsConstructor//审批状态码public enum  ApprovalStatusEnum{ START(1,"开始审批"){  @Override  ApprovalStatusEnum getNextStatus ()  {   return first_leader;  } }, first_leader(2,"第一个领导审批"){  @Override  ApprovalStatusEnum getNextStatus ()  {   return second_leader;  } }, second_leader(3,"第二个领导审批"){  @Override  ApprovalStatusEnum getNextStatus ()  {   return backups;  } }, backups(4,"备案"){  @Override  ApprovalStatusEnum getNextStatus ()  {   return null;  } }; private Integer code; private String msg; abstract ApprovalStatusEnum getNextStatus();}

在枚举类中定义抽象方法,并且在每个状态中进行具体的实现。如此在有大量的状态转移的场景中(固定的审批场景,支付场景),当前状态调用nextStatus()方法获取下一个状态。这种写法可以使得代码更加简洁干净,更加便于维护。

1. 以为精通Java 线程池,看到这些误区,还是年轻了...2. Spring Boot 集成 WebSocket,轻松实现信息推送!3. try-catch-finally 和 return 是怎么执行的?4. 在 SpringBoot 项目中,Spring Security 和 Shiro 该如何选择?最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

继续阅读
历史上的今天
4月
20
weinxin
资源分享QQ群
本站是一个IT技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
  • 版权声明:本站是Java秀团队的技术分享社区,我们会经常分享资源和教程。
  • 转载请注明:如何优雅的使用枚举 - Java秀 ☜(ˆ▽ˆ)
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: