2

我不断收到错误: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

4 回答 4

3

您的代码中有两个问题:

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

这里:

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;
}
于 2013-04-09T17:03:35.310 回答
1

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

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();
于 2013-04-09T17:27:00.517 回答
0

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

于 2013-04-09T16:59:21.887 回答
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);
    }
}
于 2013-04-09T17:02:16.737 回答