作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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) {
为了避免不安全的转换,您可以转换 DBManager
从 Map<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/
我是一名优秀的程序员,十分优秀!