當前位置:
首頁 > 知識 > code值獲取內部枚舉類對象(自定義EnumUtil PackageUtil工具類)

code值獲取內部枚舉類對象(自定義EnumUtil PackageUtil工具類)

項目里,經常涉及到枚舉類的使用。利用反射實現根據枚舉值獲取枚舉對象,可以方便我們對該枚舉對象的直接操作。

通過值實例化枚舉

package com.rq.enumutils.utils;

import com.rq.enumutils.service.EnumMessage;

public class EnumUtil {

/**

* 返回指定編碼的"枚舉"針對實現EnumMessage介面的枚舉類

* @param code

* @return SharedObjTypeEnum

* @throws

*/

public static <T extends EnumMessage> T getEnumBycode(Class<T> clazz, String code) {

for(T inner : clazz.getEnumConstants())

if(code.equals(inner.getCode()))

return inner;

return null;

}

/**

* 返回指定描述的"枚舉"

* @param desc

* @return SharedObjTypeEnum

* @throws

*/

public static <T extends EnumMessage> T getEnumByDesc(Class<T> clazz, String desc) {

for(T inner : clazz.getEnumConstants())

if(inner.getDesc().equals(desc))

return inner;

return null;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

另一種實現方案:在程序啟動時完成所有枚舉類的載入,並填入map集合中(之後操作都從該集合中獲取)

參考地址:https://www.cnblogs.com/jian-xiao/p/6036925.html

package com.rq.enumutils.common;

import com.rq.enumutils.service.EnumMessage;

import com.rq.enumutils.utils.PackageUtils;

import java.lang.reflect.Method;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

/**

* 通過code值獲取枚舉對象

* 具體代碼實現:

*

* 1).定義一個EnumMessage介面,然後每個枚舉類實現此介面;

*

* 2).定義常量保存枚舉類所在包名,以及介面全路徑;

*

* 3).在程序啟動時,讀取枚舉類所在包下的所有枚舉類的File文件,在從file文件信息中獲取每個枚舉類的全路徑類名集合A;

*

* 4).遍歷A集合,利用反射獲取每個類的class對象,再判斷該類是否實現了EnumMessage介面;

*

* 5).對於實現了EnumMessage介面的枚舉類,遍歷該枚舉類的所有對象,保存Map<Object, EnumMessage>的集合映射;

*

* 6).對枚舉類保存Map<Class, Map<Object, EnumMessage>>的映射集合。

*/

public class Constant {

/**

* 枚舉類包名集合

*/

public static List<String> pathList = initPackagePathList();

/**

* 枚舉介面類全路徑

*/

public final static String ENUM_MESSAGE_PATH = "com.rq.enumutils.service.EnumMessage";

/**

* 枚舉類對應的全路徑集合

*/

public static final List<String> ENUM_OBJECT_PATH = PackageUtils.getPackageClasses(pathList, true);

/**

* 存放單個枚舉對象 map常量定義

*/

private static Map<Object, EnumMessage> SINGLE_ENUM_MAP = null;

/**

* 所有枚舉對象的 map

*/

public static final Map<Class, Map<Object, EnumMessage>> ENUM_MAP = initialEnumMap(true);

private static List<String> initPackagePathList() {

List<String> list = new ArrayList<>();

list.add("com.rq.enumutils.enums");

return list;

}

/**

* 載入所有枚舉對象數據

*

* @param isFouceCheck 是否強制校驗枚舉是否實現了EnumMessage介面,若為false則沒有實現介面的枚舉類也會被載入

*/

private static Map<Class, Map<Object, EnumMessage>> initialEnumMap(boolean isFouceCheck) {

Map<Class, Map<Object, EnumMessage>> ENUM_MAP = new HashMap<>();

try {

for (String classname : ENUM_OBJECT_PATH) {

Class<?> cls = Class.forName(classname);

//獲取實現的介面列表

Class<?>[] iter = cls.getInterfaces();

boolean flag = false;

if (isFouceCheck) {

for (Class cz : iter) {

//找出實現目標介面的類

if (cz.getName().equals(ENUM_MESSAGE_PATH)) {

flag = true;

break;

}

}

}

if (flag == isFouceCheck) {

//自定義map集合,添加該枚舉類的所有內部枚舉類,

SINGLE_ENUM_MAP = new HashMap<>();

initialSingleEnumMap(cls);

//將新創建的map集合加入到ENUM_MAP集合中

ENUM_MAP.put(cls, SINGLE_ENUM_MAP);

}

}

} catch (Exception e) {

e.printStackTrace();

}

return ENUM_MAP;

}

/**

* 載入每個枚舉對象數據

*/

private static void initialSingleEnumMap(Class<?> cls) throws Exception {

//通過反射調用values方法

Method method = cls.getMethod("values");

EnumMessage inter[] = (EnumMessage[]) method.invoke(null, null);

for (EnumMessage enumMessage : inter) {

SINGLE_ENUM_MAP.put(enumMessage.getCode(), enumMessage);

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

介面類

package com.rq.enumutils.service;

public interface EnumMessage {

String getCode();

String getDesc();

}

1

2

3

4

5

6

7

PackageUtils

package com.rq.enumutils.utils;

import java.io.File;

import java.util.ArrayList;

import java.util.List;

public class PackageUtils {

/**

* 返回包下所有的類

*

* @param packagePathList 包名全路徑集合

* @param classWithPath 返回全路徑開關 true 自動帶上包名 false 只返回類名

* @return List<String> 包下所有的類

*/

public static List<String> getPackageClasses(List<String> packagePathList, boolean classWithPath) {

List<String> result = new ArrayList<>();

for(String packagePath : packagePathList) {

List<String> classNames = getClassName(packagePath);

String path = classWithPath ? packagePath + "." : "";

for (String className : classNames) {

//className:com.example.myFirstProject.enums.SexEnum

result.add(path + className.substring(className.lastIndexOf(".") + 1));

}

}

return result;

}

/**

* 獲取該包名全路徑下的所有class全路徑集合

* @param packageName 包名全路徑

* @return

*/

private static List<String> getClassName(String packageName) {

//根據包名獲取該package的系統路徑

String filePath = ClassLoader.getSystemResource("").getPath() + packageName.replace(".", "");

// filePath: /D:/workspace/enumutils/target/classes/com
qenumutilsenums

List<String> classNames = new ArrayList<>();

//注意:區別測試環境與開發環境

List<String> fileNames = getClassName(filePath.replace("test-classes","classes"), classNames);

return fileNames;

}

/**

* 獲取filePath文件夾下的所有class的全路徑集合

* @param filePath

* @param className

* @return

*/

private static List<String> getClassName(String filePath, List<String> className) {

File file = new File(filePath);

File[] childFiles = file.listFiles();

if (childFiles != null) {

for (File childFile : childFiles) {

if (childFile.isDirectory()) {

//遞歸獲取該文件夾下的子文件夾里的所有文件

className.addAll(getClassName(childFile.getPath(), className));

} else {

String childFilePath = childFile.getPath();

//childFilePath: D:workspaceenumutils argetclassescom
qenumutilsenumsSex.class

childFilePath = childFilePath.substring(childFilePath.indexOf("\classes") + 9, childFilePath.lastIndexOf("."));

childFilePath = childFilePath.replace("", ".");

className.add(childFilePath);

}

}

}

return className;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

這裡有個小坑

在getClassName()方法里,如果用tomcat啟動項目,getSystemResource("")會返回空指針

了解 getSystemResource(Stringname)、getSystemResourceAsStream(Stringname)、getSystemResources(Stringname)

內部實現的時候都是用到了ClassLoader system = getSystemClassLoader();的方法,獲取的ClassLoader都是App ClassLoader所以在使用tomcat運行的時候就會取不到classPath路徑下的資源,因為都是WebappClassLoader載入的。詳情點擊:https://www.aliyun.com/jiaocheng/864751.html

解決辦法:

使用當前類.class.getClassLoader().getResource(Stringname)、getResourceAsStream(Stringname)、getResources(Stringname)這三種方法。

工具類EnumUtils

package com.rq.enumutils.utils;

import com.rq.enumutils.common.Constant;

import com.rq.enumutils.service.EnumMessage;

/**

* 獲取內部枚舉類對象

*/

public class EnumUtils {

/**

* 獲取value返回枚舉對象

* @param value 內部枚舉類code值

* @param clazz 需要解析的枚舉類

* */

public static <T extends EnumMessage> T getEnumObject(Object value, Class<T> clazz){

if (value == null || clazz == null) {

return null;

}

return (T) Constant.ENUM_MAP.get(clazz).get(value);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

測試:

@Test

public void contextLoads() {

String line = "佩奇 123 00 03";

String line2 = "米奇 312 01 04";

String line3 = "青霞 111 00 04";

User user = DataUtils.Str2Obj(line, " ", User.class, 0);

User user2 = DataUtils.Str2Obj(line2, " ", User.class, 0);

User user3 = DataUtils.Str2Obj(line3," ",User.class,0);

System.out.println("user1:---"+user);

System.out.println("user2:---"+user2);

System.out.println("user3:---"+user3);

}

1

2

3

4

5

6

7

8

9

10

11

12

輸出:

實例下載:https://download.csdn.net/download/qq_41981107/10859325

---------------------

作者:咚咚大帝

原文:https://blog.csdn.net/qq_41981107/article/details/85053821

版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

code值獲取內部枚舉類對象(自定義EnumUtil PackageUtil工具類)

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

幾個Go系統可能遇到的鎖問題
架構設計三原則

TAG:程序員小新人學習 |