項目中導入大量枚舉對象,用來定義常量。隨着帶來一個問題,就是每個枚舉類都需要通過key來獲取對應枚舉的需求。
1 public enum ExamType { 2 CRAFT(1, "草稿"), 3 PASSING(2, "待審核"); 4 private int value; 5 private String typeName; 6 7 ExamType(int value, String typeName) { 8 this.value = value; 9 this.typeName = typeName; 10 } 11 //通過value獲取對應的枚舉對象 12 public static ExamType getExamType(int value) { 13 for (ExamType examType : ExamType.values()) { 14 if (value == examType.getValue()) { 15 return examType; 16 } 17 } 18 return null; 19 } 20 21 22 }
隨着項目的增大,可能存在很多枚舉對象都需要,可能都需要去實現一樣的方式,就存在了代碼冗余的問題,可惜enum對象又不不能繼承其他類
(默認繼承Enum)。所以考慮說使用反射來替代之前的方式
為了方便,將代碼寫帶一個類中
1 //接口類 2 public interface EnumMessage { 3 Integer getValue(); 4 String getMessage(); 5 } 6 7 //枚舉類 8 public enum AccountStatus implements EnumMessage { 9 Init(0,"初始化"), 10 Ready(1,"正常"), 11 ChangePassword(2,"需要修改密碼"), 12 Frozen(4,"凍結"), 13 Disabled(64,"禁用"), 14 ; 15 private final Integer _code; 16 private final String _message; 17 AccountStatus(Integer code,String message){ 18 _code=code; 19 _message=message; 20 } 21 @Override 22 public Integer getValue() { return _code;} 23 @Override 24 public String getMessage() { return _message; } 25 } 26 27 28 public enum AuditNotifyStatus implements EnumMessage { 29 Sms(2,"短信"), 30 Mail(4,"郵箱"), 31 SmsAndMail(6,"短信和郵箱"), 32 ; 33 private final Integer _code; 34 private final String _message; 35 AuditNotifyStatus(Integer code,String message){ 36 _code=code; 37 _message=message; 38 } 39 @Override 40 public Integer getValue() { return _code;} 41 @Override 42 public String getMessage() { return _message; } 43 }
常量類
1 public class Constant { 2 3 4 /** 5 * 枚舉類對應的包路徑 6 */ 7 public final static String PACKAGE_NAME = "com.lwx.util.reflex.enums"; 8 /** 9 * 枚舉接口類全路徑 10 */ 11 public final static String ENUM_MESSAGE_PATH=PACKAGE_NAME+".EnumMessage"; 12 13 /** 14 * 枚舉類對應的全路徑集合 15 */ 16 public static final List<String> ENUM_OBJECT_PATH = PackageUtil.getPackageClasses(PACKAGE_NAME, true); 17 18 /** 19 * 存放單個枚舉對象 map常量定義 20 */ 21 private static Map<Integer, EnumMessage> SINGLE_ENUM_MAP = null; 22 /** 23 * 所有枚舉對象的 map 24 */ 25 public static final Map<Class, Map<Integer, EnumMessage>> ENUM_MAP = initialEnumMap(true); 26 27 28 /**靜態初始化塊*/ 29 static { 30 31 } 32 33 /** 34 * 加載所有枚舉對象數據 35 * @param isFouceCheck 是否強制校驗枚舉是否實現了EnumMessage接口 36 * 37 * */ 38 private static Map<Class, Map<Integer, EnumMessage>> initialEnumMap(boolean isFouceCheck){ 39 Map<Class, Map<Integer, EnumMessage>> ENUM_MAP = new HashMap<Class, Map<Integer, EnumMessage>>(); 40 try { 41 for (String classname : ENUM_OBJECT_PATH) { 42 Class<?> cls = null; 43 cls = Class.forName(classname); 44 Class <?>[]iter=cls.getInterfaces(); 45 boolean flag=false; 46 if(isFouceCheck){ 47 for(Class cz:iter){ 48 if(cz.getName().equals(ENUM_MESSAGE_PATH)){ 49 flag=true; 50 break; 51 } 52 } 53 } 54 if(flag==isFouceCheck){ 55 SINGLE_ENUM_MAP = new HashMap<Integer, EnumMessage>(); 56 initialSingleEnumMap(cls); 57 ENUM_MAP.put(cls, SINGLE_ENUM_MAP); 58 } 59 60 } 61 } catch (Exception e) { 62 63 } 64 return ENUM_MAP; 65 } 66 67 /** 68 * 加載每個枚舉對象數據 69 * */ 70 private static void initialSingleEnumMap(Class<?> cls )throws Exception{ 71 Method method = cls.getMethod("values"); 72 EnumMessage inter[] = (EnumMessage[]) method.invoke(null, null); 73 for (EnumMessage enumMessage : inter) { 74 SINGLE_ENUM_MAP.put(enumMessage.getValue(), enumMessage); 75 } 76 } 77 78 79 }
工具包類

public class PackageUtil { /** * 返回包下所有的類 * @param packagePath 包名 * @return List<String> 包下所有的類 * */ public static List<String> getPackageClasses(String packagePath){ return getPackageClasses(packagePath,false); } /** * 返回包下所有的類 * @param packagePath 包名全路徑 * @param classWithPath 返回全路徑開關 true 自動帶上包名 * @return List<String> 包下所有的類 * */ public static List<String> getPackageClasses(String packagePath,boolean classWithPath){ List<String> classNames = getClassName(packagePath); List<String>result =new ArrayList<String>(classNames.size()); String path =classWithPath?packagePath+".":""; for (String className : classNames) { result.add(path+className.substring(className.lastIndexOf(".")+1)); } return result; } private static List<String> getClassName(String packageName) { String filePath = ClassLoader.getSystemResource("").getPath() + packageName.replace(".", "\\"); List<String> fileNames = getClassName(filePath, null); return fileNames; } private static List<String> getClassName(String filePath, List<String> className) { List<String> myClassName = new ArrayList<String>(); File file = new File(filePath); File[] childFiles = file.listFiles(); for (File childFile : childFiles) { if (childFile.isDirectory()) { myClassName.addAll(getClassName(childFile.getPath(), myClassName)); } else { String childFilePath = childFile.getPath(); childFilePath = childFilePath.substring(childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf(".")); childFilePath = childFilePath.replace("\\", "."); myClassName.add(childFilePath); } } return myClassName; } }
核心的獲取枚舉對象的類
1 public class EnumUtil { 2 3 4 /** 5 * 獲取value返回枚舉對象 6 * @param value 7 * @param clazz 8 * */ 9 public static <T extends EnumMessage> T getEnumObject(int value,Class<T> clazz){ 10 return (T)Constant.ENUM_MAP.get(clazz).get(value); 11 } 12 13 14 }
測試
public static void main(String[] args) { System.out.println(EnumUtil.getEnumObject(2, AuditNotifyStatus.class).getMessage());;//短信 System.out.println(EnumUtil.getEnumObject(6, AuditNotifyStatus.class).getMessage());;//短信和郵箱 }
拓展與參考
1.獲取變量的值

1 public class Test { 2 public static void main(String[] args) { 3 //構造對象 4 User user = new User(); 5 String strs[] ={"1","2","3"}; 6 user.setStrs(strs); 7 8 Method[] methods = user.getClass().getMethods(); 9 for(Method m:methods){ 10 String methodNames= m.getName(); 11 if(methodNames.equals("getStrs")){ 12 try { 13 Object obj =m.invoke(user, new Object[]{}); 14 if(obj instanceof java.lang.String []){ 15 String tempstrs [] =(String[]) obj; 16 for(String str:tempstrs){ 17 System.out.println(str); 18 } 19 } 20 } catch (Exception e) { 21 e.printStackTrace(); 22 } 23 } 24 } 25 } 26 } 27 class User{ 28 private String strs[]; 29 30 public String[] getStrs() { 31 return strs; 32 } 33 34 public void setStrs(String[] strs) { 35 this.strs = strs; 36 } 37 }
2.關於枚舉的介紹(枚舉無法通過newInstance來進行實力,本身構造就不能public,其實也就是規范)
http://whitesock.iteye.com/blog/728934
3.java反射獲取注解
http://blog.csdn.net/lufeng20/article/details/8835135
http://blog.csdn.net/liyangbing315/article/details/5181381
4.使用反射+注解完成庫表設計
http://blog.csdn.net/lufeng20/article/details/8730604
5.enum的使用,包含enumMap/enumSet
http://wenku.baidu.com/link?url=1y8U2qovo-oJkRmUBR_7sXkivFLxExzCW0J6hunDVcfIij08MX4RS45_eLptBGrujzS3q4tiGwsF4PmoGx032RBWj1IMmzOn6693B2YBVe_