java泛型工厂通过class参数+反射实现动态创建,核心是 t create(class clazz)方法,利用编译期类型推断保障安全,规避泛型擦除限制。

Java 中用泛型实现工厂模式的动态创建,核心是**让工厂能根据类型参数自动推导并创建对应实例**,避免重复写一堆 if-else 或 switch,同时保持编译期类型安全。关键不在于“泛型本身创建对象”,而在于**结合 Class 对象、反射和泛型类型擦除的应对策略**。
泛型工厂接口:定义统一创建契约
先定义一个泛型工厂接口,声明“我能创建 T 类型的对象”:
public interface GenericFactory<t> {
T create();
}</t>
这个接口本身不解决“如何动态指定 T”,只是为不同实现提供一致签名。真正动态的部分在具体工厂或调用方。
基于 Class 参数的泛型工厂(推荐)
最实用、类型安全且无需强转的方式:把 Class<t></t> 作为参数传入,利用反射 + 泛型方法推断:
- 工厂方法声明为
<t> T create(Class<t> clazz)</t></t>,调用时编译器能根据传入的 Class 自动推断返回类型 - 要求目标类有无参构造器(或用其他方式处理构造逻辑)
- 可封装成工具类或单例工厂
public class SimpleGenericFactory {
public <t> T create(Class<t> clazz) {
try {
return clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Cannot instantiate " + clazz.getName(), e);
}
}
}
// 使用示例
SimpleGenericFactory factory = new SimpleGenericFactory();
String str = factory.create(String.class); // 返回 String,无需强转
List<integer> list = factory.create(ArrayList.class); // 返回 ArrayList<integer></integer></integer></t></t>
带注册机制的泛型工厂(适合多类型、需定制初始化)
当不同类型的创建逻辑差异大(比如需要传参、依赖注入、缓存单例等),可用 Map 注册构造器函数:
- 用
Class<t></t>作 key,Supplier<t></t>作 value - 泛型方法
<t> T getInstance(Class<t> type)</t></t>查找并执行构造器 - 注册时明确类型,使用时由 Class 参数驱动泛型推断
public class RegistryGenericFactory {
private final Map<class>, Supplier>> registry = new HashMap();
public <t> void register(Class<t> type, Supplier<t> creator) {
registry.put(type, creator);
}
@SuppressWarnings("unchecked")
public <t> T getInstance(Class<t> type) {
Supplier<t> creator = (Supplier<t>) registry.get(type);
if (creator == null) throw new IllegalArgumentException("No creator registered for " + type);
return creator.get();
}
}
// 使用
RegistryGenericFactory factory = new RegistryGenericFactory();
factory.register(Connection.class, () -> DriverManager.getConnection("jdbc:h2:mem:"));
factory.register(UserService.class, () -> new UserServiceImpl(new UserDao()));
Connection conn = factory.getInstance(Connection.class); // 类型安全
UserService service = factory.getInstance(UserService.class);</t></t></t></t></t></t></t></class>
注意泛型擦除与类型安全边界
Java 运行时没有泛型信息,所以不能直接写 new T() 或 T.class。所有“动态创建 T”的方案都必须显式获得 Class<t></t> 或等效元数据:
- 不要试图在泛型类内部靠
this.getClass().getTypeParameters()获取 T 的 Class —— 它只返回 TypeVariable,无法用于 newInstance - 如果必须隐藏 Class 参数,可用工厂子类在构造时传入 Class(如
new StringFactory(String.class)),但会增加类数量 - Lombok 的
@RequiredArgsConstructor(onConstructor_ = {@SuppressWarnings("unchecked")})可简化带 Class 参数的构造
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











