无法使用参数实例化子类

时间:2013-04-09 16:43:13

标签: java

我一直收到错误:java.lang.NoSuchMethodException: com.production.workflow.MyWorkflow.<init>(com.production.model.entity.WorkflowEntity)

我有一个期望WorkflowEntity的构造函数,所以我无法弄清楚为什么它会说NoSuchMethod。有没有关于构造函数继承的东西阻止它实例化?

我的实例化工厂:

public static Workflow factory(WorkflowEntity workflowEntity) {
    try {
        Class<?> clazz = Class.forName(workflowEntity.getClassName()).asSubclass(Workflow.class);
        Constructor c = clazz.getConstructor(WorkflowEntity.class);
        Object workflowClass = c.newInstance(clazz);
        return (Workflow) workflowClass;
    } catch (Exception e) {
        e.printStackTrace();
        logger.severe("Unable to instantiate "+workflowEntity.getClassName()+" class: " + e.getLocalizedMessage());
    }

    return null;
}

工作流程类:

public class MyWorkflow extends Workflow {
//no constructors

扩展课程:

abstract public class Workflow {
    protected static final Logger logger = Logger.getLogger(Workflow.class.getName());

    private WorkflowEntity entity;
    protected WorkflowProcess workflowProcess;

    @Autowired
    private WorkflowProcessService workflowProcessService;

    /* Don't use this one */
    public Workflow() { }

    /* Default constructor */
    public Workflow (WorkflowEntity entity) {
        this.entity = entity;

        //get first workflow process
        //@todo this should factor in rule, for multiple starting points
        for (WorkflowProcessEntity workflowProcessEntity : entity.getWorkflowProcesses()) {
            workflowProcess = WorkflowProcess.factory(workflowProcessEntity);
            break;
        }
    }

4 个答案:

答案 0 :(得分:3)

您的代码中存在两个问题:

  1. 子类不会自动继承构造函数。您需要将MyWorkflow(WorkflowEntity)构造函数添加到MyWorkflow类。
  2. 您的新实例调用需要使用workflowEntity实例(而不是您现在提供的类实例)
  3. 下面:

    class MyWorkflow extends Workflow {
    
        public MyWorkflow() {
            super();
        }
    
        public MyWorkflow(WorkflowEntity entity) {
            super(entity);
        }
    }
    public static Workflow factory(WorkflowEntity workflowEntity) {
        try {
            Class<?> clazz = Class.forName(workflowEntity.getClassName())
                    .asSubclass(Workflow.class);
            Constructor<?> c = clazz.getConstructor(WorkflowEntity.class);
            Object workflowClass = c.newInstance(workflowEntity);
            return (Workflow) workflowClass;
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return null;
    }
    

答案 1 :(得分:1)

考虑构建器模式而不是工厂模式。下面是一个构建WorkFlow的示例,该WorkFlow采用WorkflowEntity构造函数参数并构建一个不采用WorkFlowEntity模式的workFlow(仅显示通过构建器提供的多个选项)。

public class WorkFlowBuilder
{
    private WorkflowEntity constructorParameter;
    private Class workflowClass;

    public WorkFlowBuilder(Class desiredWorkflowClass)
    {
        if (desiredWorkflowClass != null)
        {
            workflowClass = desiredWorkflowClass;
        }
        else
        {
            throw new IllegalArgumentException("blah blah blah");
        }
    }

    public void setConstructorParameter(final WorkflowEntity newValue)
    {
        constructorParameter = newValue;
    }

    public WorkFlow build()
    {
        Object workflowObject;

        if (constructorParameter != null)
        {
            Constructor constructor = workflowClass.getConstructor(WorkflowEntity.class);
            Object workflowObject;

            workflowObject = constructor.newInstance(workflowEntity);
        }
        else
        {
            workflowObject = workflowClass.newInstance();
        }

        return (WorkFlow)workflowObject;
    }
}

使用如下:

WorkFlowBuilder builder = new WorkFlowBuilder(MyWorkFlow.class);
WorkflowEntity entity = new WorkFlowEntity();
WorkFlow item;

entity... set stuff.

builder.setConstructerParameter(entity)
item = builder.build();

答案 2 :(得分:0)

我认为您只想将workflowEntity传递给newInstance调用的构造函数,而不是类型化的类。

答案 3 :(得分:0)

构造函数在继承期间失去了外部可见性。

您需要在MyWorkflow中重新定义它。

这样做是因为子类可能不支持超类创建过程。因此,超级对象构造函数对子类没有意义,如果它们在外面可见,它甚至是不安全的。

如果在没有WorkflowEntity实例化的情况下可以使用您的类,则还应该删除默认构造函数。只需将其从Workflow中删除即可,不要添加到MyWorkflow。

<强> UPD

您还应该考虑使用泛型来避免类转换。

public Workflow create(WorkflowEntity workflowEntity) throws 
               ClassNotFoundException, NoSuchMethodException, SecurityException
               , InstantiationException, IllegalAccessException
               , IllegalArgumentException, InvocationTargetException {

    Class<? extends Workflow> clazz = Class.forName(workflowEntity.getClassName()).asSubclass(Workflow.class);
    Constructor<? extends Workflow> c = clazz.getConstructor(WorkflowEntity.class);
    Workflow workflowClass = c.newInstance(clazz);
    return workflowClass;
}

class WorkflowEntity {

    public String getClassName() {
        return "className";
    };
}

class Workflow {

    Workflow(WorkflowEntity entity) {
    };
}

class MyWorkflow extends Workflow {

    MyWorkflow(WorkflowEntity entity) {
        super(entity);
    }
}