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 }