Java 扫描枚举类并获取属性
第一步:在 pom.xml 下导入 hutool 和 commons-lang3
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
第二步:写一个接口以规范枚举的属性
package com.zibo.api.myinterfaces;
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 {
Set<String> set = new HashSet<>();
Set<Class<?>> classes = ClassUtil.scanPackage(basePackage);
Map<String, List<EnumDto>> enums = new HashMap<>();
List<EnumDto> list;
for (Class<?> aClass : classes) {
if (ClassUtil.isEnum(aClass)) {
Method keyMethod = ClassUtil.getDeclaredMethod(aClass, "getKey");
Method valueMethod = ClassUtil.getDeclaredMethod(aClass, "getValue");
if (keyMethod == null || valueMethod == null) continue;
Object[] objs = aClass.getEnumConstants();
list = new ArrayList<>();
for (Object obj : objs) list.add(new EnumDto((Integer) keyMethod.invoke(obj), (String) valueMethod.invoke(obj)));
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。
|