JAVA-使用反射創建class的實例對象


  

 1 public class EntityUtils{
 2 
 3     // 具有默認值的類型的集合 (基本類型,基本類型的包裝類, BigDecimal , Date ,String,等)
 4     public static Map<String,Object> defaultType = new HashMap<>();
 5 
 6 
 7     static{
 8 
 9         // 基本類型
10         defaultType.put("int",0);
11         defaultType.put("byte",0);
12         defaultType.put("short",0);
13         defaultType.put("boolean",false);
14         defaultType.put("char",'a');
15         defaultType.put("float",0.1f);
16         defaultType.put("double",0.1d);
17         defaultType.put("long",0L);
18         
19         // 包裝類
20         defaultType.put("java.lang.Integer",0);
21         defaultType.put("java.lang.Byte",0);
22         defaultType.put("java.lang.Short",0);
23         defaultType.put("java.lang.Boolean",false);
24         defaultType.put("java.lang.Character",'a');
25         defaultType.put("java.lang.Float",0.1f);
26         defaultType.put("java.lang.Double",0.1d);
27         defaultType.put("java.lang.Long",0L);
28 
29         // 其他有默認值的類型
30         defaultType.put("java.lang.String","null");
31         defaultType.put("java.math.BigDecimal",BigDecimal.ZERO);
32         defaultType.put("java.util.Date",new Date());
33 
34 
35         // 獲取class的實例對象
36         public static Object getInstance(Class clazz){
37             // 枚舉 , 獲取已經定義的第一個實例對象
38             if(clazz.isEnum()){
39                 return clazz.getEnumConstants()[0];
40             }
41 
42             // 有默認值的類型
43             if(defaultType.containsKey(clazz.getName())){
44                 return defaultType.get(clazz.getName());
45             }
46 
47 
48             // 使用 builder方法 ( 會用 lombok提供的 @Builder 才會具備該方法)
49             try{
50                 Method bulder = clazz.getDeclaredMethod("builder");
51                 Object builderResult = builder.invoke(clazz);
52                 Method build = builderResult.getClass().getDeclaredMethod("build");
53                 return build.invoke(builderResult); 
54             }catch(NoSuchMethodException e){
55                 // 如果clazz沒有 builder方法,會拋出異常 NoSuchMethodException  ,此處忽略
56             }
57 
58             Object result=null;
59 
60             // 通過構造函數創建實例
61             Constructor minCt = Arrays.stream(clazz.getDeclaredConstructors())
62                                 // 取形參列表最小的構造函數
63                                 .min(Comparator.comparing(Constructor::getParamterCount))
64                                 // 如果沒有構造函數,則拋出異常
65                                 .orElseThrow(()-> new Exception("沒有可用的構造函數"));
66 
67             if(minCt.getParamterCount()==0){
68                 // 無參構造
69                 result = clazz.newInstance();
70             }else{
71                 // 有參構造
72                 Class[] paramterTypes = minCt.getParamterTypes();
73                 Object[] paramters = new Object[paramterTypes.length];
74 
75                 // 創建形參列表
76                 for(int i=0 ; i<paramterTypes.length ; i++){
77                     paramters[i] = getInstance(paramterTypes[i]);    
78                 }
79 
80                 result = minCt.newInstance(paramters);
81 
82             }                    
83 
84             if(result == null){
85                  throw new Exception("構造實例失敗,沒有可用的構造函數 或 @Builder ")
86             }
87 
88             return result;
89 
90         }
91 
92     }
93 
94 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM