gpt4 book ai didi

java - 使用泛型和反射的单例工厂

转载 作者:行者123 更新时间:2023-11-30 06:41:08 25 4
gpt4 key购买 nike

OrderDBManager、UserDBManager、ProductDBManager 扩展了 DBManager。我正在尝试创建一个单例 DBManager Factory获取不同 DBManager 类型类的实例。

但是我在使用泛型返回用户想要的确切 DBManager 类型类的实例时遇到问题。目前它仅适用于 DBManager 本身。我将感谢您的帮助!

public class DBManagerFactory {

private static final Map<String, DBManager> instances = new HashMap<>();

private static final String DB_MANAGER_PACKAGE_NAME = "ua.Test.db.";

public static DBManager getInstance(Class<? extends DBManager> dbManagerClass) {
String dbManagerClassName = dbManagerClass.getSimpleName();
DBManager dbManager = instances.get(dbManagerClassName);

if(dbManager == null){
Class clazz = Class.forName(DB_MANAGER_PACKAGE_NAME + dbManagerClassName);
dbManager = (DBManager)clazz.newInstance();
instances.put(dbManagerClassName, dbManager);
}
return dbManager;
}}

最佳答案

But I have a problem using generics to return an instance of exact DBManager type class user wants.

要在方法中返回特定类,您应该指定一个作用域方法参数化类型,该类型允许类的客户端指定该方法应返回哪种类型。

您可以这样声明该方法:

public static <T extends DBManager> T getInstance(Class<T> dbManagerClass)  {

为了避免不安全的转换,您可以转换 DBManagerMap<String, DBManager> 检索实例到 T extends DBManager使用 Class#cast(Object ) 键入在强制转换 DBManager 之前为您执行类型检查的方法实例:

T dbManager = dbManagerClass.cast(instances.get(dbManagerClassName));

最后,获取类的方法:

Class clazz = Class.forName(DB_MANAGER_PACKAGE_NAME + dbManagerClassName);

不是必需的,因为您已经将类作为方法的参数。
直接使用即可。

以下是实现此解决方案的示例代码:

public class DBManagerFactory {

private static final Map<String, DBManager> instances = new HashMap<>();

public static <T extends DBManager> T getInstance(Class<T> dbManagerClass) {

final String dbManagerClassName = dbManagerClass.getSimpleName();

T dbManager = dbManagerClass.cast(instances.get(dbManagerClassName));

if (dbManager == null) {
try {
dbManager = dbManagerClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace(); // or better log it
throw new RuntimeException("faillure during reflection instantiation for class " + dbManagerClass.getName(), e);
}
instances.put(dbManagerClassName, dbManager);
}

return dbManager;
}

}

通过这些修改,客户端类可以通过以下方式调用该方法:

DBManager instance = DBManagerFactory.getInstance(DBManager.class);
DBManagerChild child = DBManagerFactory.getInstance(DBManagerChild.class);

关于java - 使用泛型和反射的单例工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44354699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com