简介: 所谓工厂模式,创建一个对象的接口,让子类决定实例化哪一个工厂类,使其创建过程延迟到了子类。 所谓的万能工厂类,通过反射调用的方式,获取到子类对象,并实例化返回,此外本案例还通过重载的方式,允许了有参和无参两种获取到实例的方式。
/**
* @author: demo
* @date: 2021/8/7
* @describe:
*/
public class MyFactory {
/**
* 构造器私有化
*/
private MyFactory() {
}
/**
* 获得实例
* @param clazz
* @param <T>
* @return
*/
public static <T> T getInstance(Class<T> clazz) {
T instance = null;
try {
instance = clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
return instance;
}
/**
* 重载,获得实例
* @param clazz
* @param obj
* @param <T>
* @return
*/
public static <T> T getInstance(Class<T> clazz, Object... obj) {
T instance = null;
Class[] c = new Class[obj.length];
Object[] o = new Object[obj.length];
try {
for (int i = 0; i < obj.length; i++) {
c[i] = getType(obj[i]);
o[i] = obj[i];
}
instance = clazz.getDeclaredConstructor(c).newInstance(o);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | NullPointerException e) {
e.printStackTrace();
}
return instance;
}
/**
* 防止集合的匿名内部类赋值返回直接父类的class对象,造成找不到对应方法异常
* @param obj
* @return
*/
private static Class getType(Object obj) {
if (obj instanceof Map) {
return Map.class;
} else if (obj instanceof List) {
return List.class;
} else if (obj instanceof Set) {
return Set.class;
} else {
return obj.getClass();
}
}
}
测试代码:
/**
* 使用了Lombok插件快速生成代码
* @author: demo
* @date: 2021/8/7
* @describe:
*/
@Data
public class Person {
private String name;
private Map<String, List> map;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(String name, Map<String, List> map) {
this.name = name;
this.map = map;
}
public static void main(String[] args) {
Person person = MyFactory.getInstance(Person.class, "a", new HashMap<String, List>() {
{
put("a", new ArrayList() {
{
add("aaaaa");
}
});
}
});
System.out.println(person.toString());
}
}
测试结果:
但是,利用反射进行传参进行有参构造的实例化固好,但有一个无法避免的问题,即无法在编译期间发现参数类型是否与构造方法的类型相匹配。