简介: 所谓工厂模式,创建一个对象的接口,让子类决定实例化哪一个工厂类,使其创建过程延迟到了子类。 所谓的万能工厂类,通过反射调用的方式,获取到子类对象,并实例化返回,此外本案例还通过重载的方式,允许了有参和无参两种获取到实例的方式。
1 /** 2 * @author: demo 3 * @date: 2021/8/7 4 * @describe: 5 */ 6public class MyFactory { 7 /** 8 * 构造器私有化 9 */ 10 private MyFactory() { 11 } 12 13 /** 14 * 获得实例 15 * @param clazz 16 * @param <T> 17 * @return 18 */ 19 public static <T> T getInstance(Class<T> clazz) { 20 T instance = null; 21 try { 22 instance = clazz.getDeclaredConstructor().newInstance(); 23 } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { 24 e.printStackTrace(); 25 } 26 return instance; 27 } 28 29 /** 30 * 重载,获得实例 31 * @param clazz 32 * @param obj 33 * @param <T> 34 * @return 35 */ 36 public static <T> T getInstance(Class<T> clazz, Object... obj) { 37 T instance = null; 38 Class[] c = new Class[obj.length]; 39 Object[] o = new Object[obj.length]; 40 try { 41 for (int i = 0; i < obj.length; i++) { 42 c[i] = getType(obj[i]); 43 o[i] = obj[i]; 44 } 45 instance = clazz.getDeclaredConstructor(c).newInstance(o); 46 } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | NullPointerException e) { 47 e.printStackTrace(); 48 } 49 return instance; 50 } 51 52 /** 53 * 防止集合的匿名内部类赋值返回直接父类的class对象,造成找不到对应方法异常 54 * @param obj 55 * @return 56 */ 57 private static Class getType(Object obj) { 58 if (obj instanceof Map) { 59 return Map.class; 60 } else if (obj instanceof List) { 61 return List.class; 62 } else if (obj instanceof Set) { 63 return Set.class; 64 } else { 65 return obj.getClass(); 66 } 67 } 68}
测试代码:
1 /** 2 * 使用了Lombok插件快速生成代码 3 * @author: demo 4 * @date: 2021/8/7 5 * @describe: 6 */ 7@Data 8public class Person { 9 private String name; 10 private Map<String, List> map; 11 12 public Person() { 13 } 14 15 public Person(String name) { 16 this.name = name; 17 } 18 19 public Person(String name, Map<String, List> map) { 20 this.name = name; 21 this.map = map; 22 } 23 24 public static void main(String[] args) { 25 Person person = MyFactory.getInstance(Person.class, "a", new HashMap<String, List>() { 26 { 27 put("a", new ArrayList() { 28 { 29 add("aaaaa"); 30 } 31 }); 32 } 33 }); 34 System.out.println(person.toString()); 35 } 36}
测试结果:

但是,利用反射进行传参进行有参构造的实例化固好,但有一个无法避免的问题,即无法在编译期间发现参数类型是否与构造方法的类型相匹配。
