首页 > 编程语言 >Java 扫描枚举类并获取属性

Java 扫描枚举类并获取属性

时间:2023-02-22 21:07:56浏览次数:37  
标签:Java EnumDto 扫描 zibo 枚举 api import com


Java 扫描枚举类并获取属性

文章目录

  • ​​Java 扫描枚举类并获取属性​​
  • ​​第一步:在 pom.xml 下导入 hutool 和 commons-lang3​​
  • ​​第二步:写一个接口以规范枚举的属性​​
  • ​​第三步:写一个枚举属性包装类​​
  • ​​第四步:写两个实体测试类​​
  • ​​第五步:写一个枚举扫描工具类​​
  • ​​第六步:代码测试​​
  • ​​第七步:运行结果​​
  • ​​第八步:实际使用说明​​

第一步:在 pom.xml 下导入 hutool 和 commons-lang3

<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M2</version>
</dependency>

<!--commons-lang3-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>

第二步:写一个接口以规范枚举的属性

package com.zibo.api.myinterfaces;

// 枚举实现该接口,用于约束枚举必须有 key 和 value 两个字段,及其 getter 方法,以符合反射获取和调用方法
public interface MyEnum {
int getKey();
String getValue();
}

第三步:写一个枚举属性包装类

package com.zibo.api.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

// 封装枚举数据
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EnumDto {
private Integer key;
private String value;
}

第四步:写两个实体测试类

Dog

package com.zibo.api.enums;

import com.zibo.api.myinterfaces.MyEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum Dog implements MyEnum {
A(1, "刘备"),
B(2, "关羽"),
C(3, "张飞");
private int key;
private String value;
}

Cat

package com.zibo.api.enums;

import com.zibo.api.myinterfaces.MyEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum Cat implements MyEnum {
A(1, "大哥"),
B(2, "二哥"),
C(3, "三哥");
private int key;
private String value;
}

第五步:写一个枚举扫描工具类

注意使用时需要根据实际需求进行调整!

package com.zibo.api.utils;

import cn.hutool.core.util.ClassUtil;
import com.zibo.api.entity.EnumDto;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

// 获取枚举类的所有属性
public class EnumUtils {

// 扫描的包路径
private static final String basePackage = "com.zibo.api";

public static Map<String, List<EnumDto>> enums = null;

static {
try {
enums = getEnums();
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}

private EnumUtils() {}

private static Map<String, List<EnumDto>> getEnums() throws InvocationTargetException, IllegalAccessException {
// map 的规则是覆盖,如果存在多个相同的 key 不会报错,因此写一个 set 以验证之
Set<String> set = new HashSet<>();
// 扫描该包路径下所有class文件
Set<Class<?>> classes = ClassUtil.scanPackage(basePackage);
// 用来存放扫描到的符合要求的【所有枚举】信息,要求参考“ClassUtil.getDeclaredMethod”
Map<String, List<EnumDto>> enums = new HashMap<>();
// 用来存放【当前枚举】的所有属性
List<EnumDto> list;
for (Class<?> aClass : classes) {
// 判断类是否为枚举类型
if (ClassUtil.isEnum(aClass)) {
// 枚举必须有这两个字段,当然也可以根据需求定义更多,将 EnumDto 做相应调整即可!
Method keyMethod = ClassUtil.getDeclaredMethod(aClass, "getKey");
Method valueMethod = ClassUtil.getDeclaredMethod(aClass, "getValue");
if (keyMethod == null || valueMethod == null) continue;
// 得到 enum 的所有实例:一个数组,该数组包含组成此 Class 对象表示的枚举类的值,按它们声明的顺序
Object[] objs = aClass.getEnumConstants();
// 装载当前枚举所有值
list = new ArrayList<>();
for (Object obj : objs) list.add(new EnumDto((Integer) keyMethod.invoke(obj), (String) valueMethod.invoke(obj)));
// 装载当前枚举 list 到所有枚举 map
String enumName = aClass.getName().substring(aClass.getName().lastIndexOf(".") + 1);
String prefix = "com.zibo";
String moduleName = aClass.getName().substring(aClass.getName().indexOf(".", prefix.length()) + 1, aClass.getName().indexOf(".", prefix.length() + 1));
String key = StringUtils.join(moduleName, ".", enumName);
if (!set.add(key)) throw new RuntimeException("同一模块下存在重复枚举名!格式:模块名.枚举名,内容:" + key);
enums.put(key, list);
}
}
return enums;
}
}

第六步:代码测试

package com.zibo.api;

import com.zibo.api.utils.EnumUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class MyEnumTest {
@Test
public void test() {
EnumUtils.enums.forEach((k, v) -> {
System.out.println(k + ":");
v.forEach(System.out::println);
});
}
}

第七步:运行结果

api.Dog:
EnumDto(code=1, text=刘备)
EnumDto(code=2, text=关羽)
EnumDto(code=3, text=张飞)
api.Cat:
EnumDto(code=1, text=大哥)
EnumDto(code=2, text=二哥)
EnumDto(code=3, text=三哥)

第八步:实际使用说明

1、(必须)要返回的枚举必须遵守 MyEnum 接口规范,不一定要实现该接口,但必须有 getKey 和 getValue 两个方法;

2、(建议)建议在登录完成后等场景调用一次该接口(写成的api接口),并缓存到客户端;

3、(提示)本接口全部相关类(用来测试的测试实体类除外):EnumDto、MyEnum、EnumUtils。


标签:Java,EnumDto,扫描,zibo,枚举,api,import,com
From: https://blog.51cto.com/u_13272819/6079417

相关文章

  • 【Java对象转换】002- Java 对象与 Map 互转
    文章目录​​【Java对象转换】002-Java对象与Map互转​​​​一、Java对象与Map概述​​​​1、Java对象​​​​2、Map​​​​二、Java对象与Map互转​​​​1......
  • Java 截取字符串 split 方法与 substring 方法简单比较
    Java截取字符串split方法与substring方法简单比较文章目录​​Java截取字符串`split`方法与`substring`方法简单比较​​​​0、结论​​​​1、截取目标​​​​......
  • 【Java对象转换】001- Java 对象与 JSON 互转
    文章目录​​【Java对象转换】001-Java对象与JSON互转​​​​一、Java对象与JSON概述​​​​1、Java对象​​​​2、JSON​​​​二、JSON解析及与Java对象互转......
  • 【JavaScript】JS引擎中执行上下文如何顺序执行代码
    首先我们知道JavaScript引擎包括一个调用栈和堆,调用栈是代码实际执行的地方,使用执行上下文(执行环境)来完成;堆是非结构化的内存池,存储了应用程序所需要的所有对象。执行上......
  • java环境搭建
    百度下载jdk8(8u181)先登录甲骨文再下载,安装后要记得安装目录在我的电脑,属性,高级设置,环境变量里新建JAVA_HOME环境名,地址是安装目录找到Path在里面添加%JAVA_HOME%/bin和......
  • Java帝国的诞生
    Java帝国的诞生C&C++1972年C诞生贴近硬件,运行极快,效率极高。操作系统,编译器,数据库,网络系统等指针和内存管理1982年C++诞生面向对象兼容C图形领域、游戏等1995年J......
  • Java数据类型,变量命名的标准 (AJCG),分支和循环,文档注释的要求
    Java数据类型,变量,分支和循环Java中的八大基本数据类型数据类型占用字节数数据范围byte1B-128~127short2B-32768~32767int4B-2^31~2^31-1......
  • Java多线程技能-方法介绍
    java多线程技能技术点:线程的启动如何使线程暂停如何使线程停止线程的优先级线程安全相关的问题方法currentThread()currentThread()方法可返回代码段正在被哪......
  • Java-模块化
    模块的基本使用模块使用步骤创建模块(创建模块,创建包,创建类,定义方法)-创建两个模块myOne,myTwo在模块的src目录下创建module-info.java的描述性文件,该文件专门定义模块......
  • IDEA打开项目代码,识别不了资源文件(java文件、yml文件等),找不到或无法加载主类 com.xxxx
    如图所示,识别不了java文件和yml文件   点开EditConfigurations发现找不到启动类  运行会报错:  可以尝试如下解决办法办法:        然......