我有这个容器:
public class DIContainer {
protected static DIContainer instance;
protected Hashtable<Class<?>, Class<?>> classMap;
protected DIContainer(){
this.classMap = new Hashtable<Class<?>, Class<?>>();
}
public static DIContainer getInstance(){
if (DIContainer.instance == null)
DIContainer.instance = new DIContainer();
return DIContainer.instance;
}
public void regClass(Class<?> interf, Class<?> classToReg){
this.classMap.put(interf, classToReg);
}
public Object create(Class<?> interf, boolean lazy) throws Exception{
if(!this.classMap.containsKey(interf))
throw new Exception("No such class registered with "+interf.getName()+" interface");
else if(lazy == false)
return this.classMap.get(interf).newInstance();
else
return this.classMap.get(interf);
}
}
而且,如果选择了延迟创建选项,那么我需要延迟创建一个对象(这样它将创建一些实现相同接口的子对象)。因此,当为该子对象调用第一个方法时,它将实例化“真实”对象。我不知道要使用的确切方法,该怎么办?如何检查是否为该对象调用了任何方法?
现在,您可以看到,我只是将其作为惰性创建尝试了:
return this.classMap.get(interf);
但这给了我一个错误:
java.lang.ClassCastException
我是否需要其他方法来检查是否对该子对象进行了任何调用,因为创建完成后,我将退出“创建”方法,何时调用该方法,我需要以某种方式进行检查?
这是我的测试接口及其实现类:
public interface Interface1 {
public String getName();
public void setName(String name);
}
public class Class1 implements Interface1{
String name;
Class1(){}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
这就是我测试的方式:
public class Main {
public static void main(String[] args) throws Exception{
DIContainer dic = DIContainer.getInstance();
dic.regClass(Interface1.class, Class1.class);
Interface1 t1 = (Interface1) dic.create(Interface1.class, true);
附言如果我将延迟创建设置为false,那么它将起作用。
最佳答案
在您的情况下,行return this.classMap.get(interf);
返回一个Class
对象,该对象先前已通过this.classMap.put(interf, classToReg)
行放置在地图中。 Class
对象绝对不能转换为Interface1
接口,因为它没有实现它,从而导致ClassCastException
。
您真正需要的是返回一种包装器,该包装器实现Interface1
接口并包装延迟实例化的类。当调用接口的任何方法时,包装器将实例化实际对象并委托该调用。
如果要延迟初始化任意类,最直接的选择是使用Java的dynamic proxy。