IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Java 扫描枚举类并获取属性 -> 正文阅读

[游戏开发]Java 扫描枚举类并获取属性

Java 扫描枚举类并获取属性

第一步:在 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。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:49:29  更:2022-04-09 18:51:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 20:58:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码