我在这里看到了类似的问题,但是,我问这个问题基于this。
我已经实现了接受的答案给出的建议,但是,我仍然看到正在创建两个实例。目标是我希望仅在特定方法调用上创建实例。我不能在Java 6的接口中使用静态方法。
我尝试过的代码
private static final Map<String, IRule> instancesMap = new Hashtable<String, IRule>();
@SuppressWarnings("unchecked")
public static <T extends IRule> T getRuleInstance(String clazz) {
try {
if (isInstanceCreated(clazz)) {
T type = (T) instancesMap.get(clazz);
if (logger.isDebugEnabled()) {
logger.debug("Found a cashed instance of " + clazz + ". Returning " + type);
}
return type;
} else {
Class<?> ruleObject = Class.forName(clazz);
Constructor<?> clazzConstructor = ruleObject.getDeclaredConstructor();
/**
* Hack encapsulation
*/
clazzConstructor.setAccessible(true);
IRule iRuleInstance = (IRule) clazzConstructor.newInstance();
if (logger.isDebugEnabled()) {
logger.debug("The instance of class " + clazz + " " + iRuleInstance + " has been created.");
}
instancesMap.put(clazz, iRuleInstance);
return (T) iRuleInstance.getInstance();
}
} catch (ClassNotFoundException e) {
logger.error("ClassNotFoundException", e);
} catch (IllegalAccessException e) {
logger.error("IllegalAccessException", e);
} catch (SecurityException e) {
logger.error("SecurityException", e);
} catch (NoSuchMethodException e) {
logger.error("NoSuchMethodException", e);
} catch (IllegalArgumentException e) {
logger.error("IllegalArgumentException", e);
} catch (InvocationTargetException e) {
logger.error("InvocationTargetException", e);
} catch (InstantiationException e) {
logger.error("InstantiationException", e);
}
return null;
}
private static boolean isInstanceCreated(String clazz) {
return instancesMap.containsKey(clazz);
}
答案 0 :(得分:1)
如果有缓存命中,则返回缓存的内容(instancesMap.get(clazz)
)。但如果没有命中,你缓存一件事(instancesMap.put(clazz, iRuleInstance)
)并返回另一件事(iRuleInstance.getInstance()
)。这没有意义。
添加到地图后不要致电getInstance
,只需将其退回:
instancesMap.put(clazz, iRuleInstance);
return (T) iRuleInstance;
或者,调用getInstance,但缓存它:
(T) instance = iRuleInstance.getInstance();
instancesMap.put(clazz, instance);
return (T) instance;
无论哪种方式,你都必须返回你缓存的内容,以便它与你的缓存命中逻辑相匹配。
答案 1 :(得分:0)
您是否需要具备IRule
的具体实现? - 您将从实施中使用哪些方法?它们不能被推广到界面本身吗?如果是这种情况,您可以使用Map<Class<? extends IRule>, IRule>
地图来管理您的实例。