我有这个容器:

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

10-05 22:23