Java枚举中定义属性

这篇具有很好参考价值的文章主要介绍了Java枚举中定义属性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

刚接触枚举时的例子太简单,就一个Season枚举类,里面四个常量值,后来开发中看到枚举中定义属性就很看不惯。这里梳理下Java枚举中定义属性,以及枚举在开发中的实际应用举例。

1、复习枚举

  • Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一年的 12 个月份
  • Java枚举类使用enum定义,各个常量之间用逗号分隔
enum Color 
{ 
    RED, GREEN, BLUE; 
} 
  • 枚举类中引用每一个常量值,用类名.常量
public class Test
{
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}

//输出RED
  • 初学时的经典例子,和switch连用
public class MyClass {
  public static void main(String[] args) {
    Color myVar = Color.BLUE;

    switch(myVar) {
      case RED:
        System.out.println("红色");
        break;
      case GREEN:
         System.out.println("绿色");
        break;
      case BLUE:
        System.out.println("蓝色");
        break;
    }
  }
}
//蓝色
  • 内部类中使用枚举
public Class MyDemo{

	 enum Color
	    {
	        RED, GREEN, BLUE;
	    }
	    
	public void doSome(){
       ....
	}
 
}

2、自定义属性

枚举类的语法结构虽然和普通类不一样,但是经过编译器之后产生的也是一个class文件。该class文件再反编译回来可以看到实际上是生成了一个类。该类继承了java.lang.Enum<E>,且所有的枚举值都是 public static final 的,以上枚举类Color可理解为:

//java为单继承,因此不能再继承其他类
class Color extends java.lang.Enum
{
     public static final Color RED = new Color();
     //枚举中的常量,可以看作是一个个对象,看到这儿应该get到枚举中定义属性的操作了
     public static final Color BLUE = new Color();
     public static final Color GREEN = new Color();
}

看到上面的反编译代码,对枚举中定义成员变量,枚举值有属性值的操作应该捋顺了!举个定义属性的简单例子:

public enum Domain {
 
 
    XB("11","西北"),
    HD("13","华东"),
    DB("14","东北"),
    HB("15","华北");
 
    private String code;
    private String name;
 
    Domain(String code,String name) {
        this.code = code;
        this.name = name;
    }
 
    public String getCode() {
        return code;
    }
    public String getName(){
        return name;
    }
}

3、自定义属性枚举类和常量的对比

上面提到所有的枚举值都是 public static final 的,可能会有疑问:那直接用常量不得了?

===>

自定义属性枚举是常量的升级版,二者有各自的应用场景。当就只需要一个静态变量名 = 值 时,直接用常量自然最快,如:

Java枚举中定义属性

但当你的一个值背后需要连着多个信息时,就只能用枚举+自定义属性来表达!

4、常用方法

enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。

枚举类中常用的三个方法:values()、ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

  • values() 返回枚举类中所有的值
  • ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样
  • valueOf()方法返回指定字符串值的枚举常量
enum Color
{
    RED, GREEN, BLUE;
}
 
public class Test
{
    public static void main(String[] args)
    {
        // 调用 values()
        Color[] arr = Color.values();
 
        // 迭代枚举
        for (Color col : arr)
        {
            // 查看索引
            System.out.println(col + " at index " + col.ordinal());
        }
 
        // 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException
        System.out.println(Color.valueOf("RED"));
        // System.out.println(Color.valueOf("WHITE"));
    }
}

运行结果:

RED at index 0
GREEN at index 1
BLUE at index 2
RED

5、枚举自定义属性在开发中的应用:字典表

看一个例子,有一个审核流的需求,审核状态只有四种,定义字典表:

Java枚举中定义属性

为了后面写代码方便和规范,定义下面这个枚举类

import brave.internal.Nullable;

import java.util.HashMap;
import java.util.Map;

public enum AuditStatusEnum {
    BEFORE("before","待提交"),
    WAIT("wait", "待审核"),
    NO("no", "审核未通过"),
    PASS("pass","审核通过");

    String code;
    String name;

    AuditStatusEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }

    private static final Map<String, AuditStatusEnum> mappings = new HashMap<>(5);

    static {
        for (AuditStatusEnum statusEnum : values()) {
            mappings.put(statusEnum.code, statusEnum);
        }
    }

    public String getCode(){
        return code;
    }

    public String getName(){
        return name;
    }

    @Nullable
    public static AuditStatusEnum resolve(@Nullable String code) {
        return (code != null ? mappings.get(code) : null);
    }
}

分析:

  • 两个属性,一个为code,一个为中文名,常见操作
  • values()方法获取枚举成员的所有值,返回一个数组
  • 写静态代码块,遍历上面的数组,以枚举值的code为键,以枚举值本身为值,放进Map集合
  • 静态方法resolve()则是根据枚举值的code查询枚举值
  • 定义静态方法resolve,妙在利用了Java类加载的时机之一 : 访问静态方法 。访问静态方法 ==> 类加载 ==> 静态代码块执行 ⇒ 枚举值被全存到Map中,方便后面查询
/定义了上面的字典对应的枚举类后,写业务逻辑代码:


if (xxDto.getAuditCode().equals(AuditStatusEnum.NO.getCode())){
	return new MyException("审核未通过,不可操作!");
}





Java枚举中定义属性

6、补充:入参校验

最后,工作时看到同事写的这个入参校验也蛮有意思,记录一下:


有个需求,它的某个接口有个传参,如排序字段orderField,该字段的可取值固定,只有create_time和name,为了防止非法传参,需要对这个入参做校验,此时也可用自定义属性的枚举类实现。

//当然想实现这个校验,直接把字段塞进集合,判断传参的值在不在集合中也能实现
//但这样一来后期扩展不方便,二来则是每个公司的代码规范要求

接下来演示枚举类:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

@Getter
@AllArgsConstructor
public enum OrderFieldEnum {
    CREATE_TIME("createTime", "create_time"),
    NAME("name","name");
    
    private final String value;  //值
    private final String field;  //对应数据库中的字段,方便后面写业务和Mapper层代码
    
    private static final Map<String, OrderFieldEnum> map = new HashMap<>();
    

    @JsonCreator
    public static OrderFieldEnum check(String value) {
    	//这里的判断map为空则遍历枚举类的值放进Map中
    	//这个操作和上面的利用类加载时机初始化Map集合一个目的
        if (map.isEmpty()) {
            for (OrderFieldEnum orderFieldEnum : OrderFieldEnum.values()) {
                map.put(orderFieldEnum.getValue(), orderFieldEnum);
            }
        }
        //如果在Map中找不到对应的key和传入的字段相等,则认为非法传参,即不支持这个排序字段
        if (!map.containsKey(value)) {
     
            throw new MyExceptionHandler("不支持这个排序字段");  //自定义异常,在全局异常处理器处理
        }
        //否则返回整个枚举对象
        return map.get(value);
    }

    @JsonValue
    public String getValue() {
        return value;
    }
}

此时,校验入参可:

OrderFieldEnum.check(dto.getOrderField().getValue());

记录下他的另一种校验的实现方式,虽然写多了,但通用性更强

checkParamRegion(dto.getOrderField(), List.of(OrderFieldEnum.CREATE_TIME, OrderFieldEnum.NAME));

public void checkParamRegion(Object param, Collection<?> regions) {
		//判断Object param是集合类型还是非集合
        if (param instanceof List) {
            List list = (List) param;
            for (Object o : list) {
                if (!regions.contains(o)) {
	                throw new MyExceptionHandler("参数超过了给定范围");
                }
            }
        } else {
            if (!regions.contains(param)) {
                throw new MyExceptionHandler("参数超过了给定范围");
            }
        }
    }

最后,写mapper层的排序,拿排序字段可:文章来源地址https://www.toymoban.com/news/detail-471992.html

OrderFieldEnum.CREATE_TIME.getField()

到了这里,关于Java枚举中定义属性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java】定义一个表示学生信息的类,要求如下:(1)学生的属性包括:学号、姓名、性别、年龄和课程成绩(5门课,其中包括Java);

    题目要求:定义一个表示学生信息的类,要求如下:(1)学生的属性包括:学号、姓名、性别、年龄和课程成绩(5门课,其中包括Java);(2)创建带参数的构造方法;(3)获取学生的属性信息;(4)根据学生类,创建五个该类的对象,要求对象数组,并打印五个学生的

    2024年02月07日
    浏览(45)
  • upf低功耗的一个简单的例子

    这里是一个uart_top模块里面例化了两个uart,分别给两个模块给了power_switch,用于电源控制,对这两个模块分别进行隔离关断来写一个简单的upf。 注意点1:电压域的中这里没有用到scope的内容,create_power_domain {uart_top} 这表达的含义就是uart_top为顶层的意思,不需要使用scope。 注

    2024年02月13日
    浏览(39)
  • 编程小窍门: 一个简单的go mutex的小例子

    本期小窍门用到了两个组件 mutex 这个类似其他语言的互斥锁 waitGroup 这个类似其他语言的信号量或者java的栅栏锁 示例如下

    2024年02月13日
    浏览(42)
  • Effective Java笔记(3)用私有构造器或者枚举类型强化 Singleton 属性

            Singleton 是指仅仅被实例化一次的类 。Singleton 通常被用来代表一个无状态的对象,如函数,或者那些本质上唯一的系统组件 。 使类成为 Singleton会使它的害户端测试变得十分困难 ,因为不可能给 Singleton 替换模拟实现,除非实现一个充当其类型的接口 。      

    2024年02月15日
    浏览(52)
  • 《Effective Java》第三条 用私有构造器或者枚举类型强化Singleton属性

    Singleton其实就是单例,即一个类在一个应用程序中只被实例化一次,只有一个对象。 本节讨论三种实现方式 私有构造+共有成员 私有构造+静态工厂方法+私有成员 枚举实现 1、共有成员 构造方法私有,有一个该类类型的公有不可变的实例域。 1.1 code 当类加载的时候就会创建

    2024年02月16日
    浏览(39)
  • 【C语言】一个简单的C语言例子,判断一个数是否为2的幂

    目录 步骤和解释: 示例程序: 代码解释: 十进制转化成二进制: 代码解释: 首先我们需要知道的是2的幂次方在二进制中都是只有一个1的: 所以现在我们可以判断,如果二进制中只有一个1,其他位都是0,则这个数就是2的幂次方; 接着,我们使用这个数-1进行与计算,因

    2024年02月14日
    浏览(56)
  • Winform自定义控件与自定义属性的简单使用

    Winform自定义控件和属性的学习  最近新文章:C#Winform批量获取CSV内容展示,并保存 目录 一、自定义控件的使用 1.在Winform程序中添加新建项,选择Windows窗体用户控件 2.拖拽使用自定义控件到主窗体中 注意点① : 二、自定义控件的自定义属性 1.在自定义控件中添加一个控件

    2023年04月15日
    浏览(40)
  • 使用java写一个对接flink的例子

    Maven依赖: 其中, flink.version 和 scala.binary.version 都需要替换为实际使用的版本号。 模拟数据生成: 这个程序使用 Flink 的 generateSequence() 方法生成 1000 个从 0 到 999 的数字作为模拟数据,将它们转化为字符串并拼接成键值对,然后使用 Flink 的 Kafka 生产者将数据写入到 Kafka 的

    2024年02月15日
    浏览(42)
  • java 中开源的html解析库Jsoup 简单例子

            下面是一个使用Jsoup库解析HTML的简单Java例子。这个例子展示了如何使用Jsoup从一个HTML字符串中提取数据。         首先,确保你已经将Jsoup作为依赖项添加到你的项目中。如果你使用的是Maven,可以在`pom.xml`文件中添加以下依赖:                   然后

    2024年02月22日
    浏览(42)
  • 【Java 28岁了】一个有趣的例子,再推荐一些经典好书(文末惊喜福利)

    众所周知,C语言和Java语言是两种不同的编程语言,它们的关系可以描述为Java语言是在C语言的基础上发展而来的一种高级编程语言。C语言是一种面向过程的编程语言,主要用于系统编程和底层开发,而Java语言则是一种面向对象的编程语言,主要用于开发跨平台的应用程序和

    2024年02月09日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包