【发布时间】:2014-05-25 08:01:52
【问题描述】:
我正在尝试使用泛型来保持良好的抽象。
在几个班级之间移动“未经检查的演员”之后,我不得不选择哪个“未经检查的演员”是较小的邪恶,这就是我得到的:
public class DaoFactory {
private static DaoFactory instance;
private HashMap<String, Dao<?, BigDecimal>> registeredClasses = new HashMap<String, Dao<?, BigDecimal>>();
private DaoFactory() {
}
public static synchronized DaoFactory getInstance() {
if (instance == null)
instance = new DaoFactory();
return instance;
}
public <T> void registerDao(String daoId, Dao<T, BigDecimal> d) {
registeredClasses.put(daoId, d);
}
@SuppressWarnings("unchecked")
public <T> Dao<T, BigDecimal> createDao(String daoId) {
return (Dao<T, BigDecimal>) (registeredClasses.get(daoId)).createDao();
}
}
如您所见,我添加了一个@SuppressWarnings("unchecked"),我在其中收到“未经检查的演员表”警告。
这就是问题所在:registeredClasses 不能 是 HashMap<String, Dao<T, BigDecimal>>,因为我需要将类型参数 T 添加到 DaoFactory 类(它将是 class DaoFactory<T> )。如果我添加该参数,那么instance = new DaoFactory(); 也需要<T>。但它在一个静态数学中(DaoFactory 是一个单例),所以我不能使用T。所以我使用HashMap<String, Dao<?, BigDecimal>> registeredClasses 而不是HashMap<String, Dao<T, BigDecimal>> registeredClasses。
所以我在这个工厂类中有“<T>-world”和“<?>-world”。所以我必须从Dao<?, BigDecimal> 转换为Dao<T, BigDecimal> 并使用@SuppressWarnings("unchecked")。你觉得这可以接受吗?
【问题讨论】:
-
嗯,解决方案基本上是类型不安全的,因为
registeredClasses是一个非同质映射,包含各种类型的 Dao。那肯定会在某处冒泡。 -
这很奇怪,但是,您在
Dao的实例上调用createDao()以获得相同类型的Dao。 -
有些类是
extends Dao(例如:Impl1Dao),它们有它们的createDao()return new Impl1Dao(); -
那么
Dao既是DAO又是DAO工厂?这是一种奇怪的做法。 -
正如我所说,我会使用配套工厂类。它可以是 DAO 类中的一个小型静态类。但是,如果您没有从中获得任何收益,请坚持现有的。无论如何,所有这些都与您关于类型不安全的问题无关。