2013-04-09 25 views
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; 
     } 
    } 

回答

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; 
} 
0

我覺得你只是想在workflowEntity通入的構造newInstance調用,而不是類型化的類。

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); 
    } 
} 
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();
+0

是否有優勢,這種方法在工廠?圖書館中通用的Java實踐更標準嗎? – Webnet 2013-04-09 19:11:27

+1

我的首選是在構造函數參數數量可變時使用構建器。Factory看起來不錯,但就你而言,我會將MyWorkFlow.class作爲工廠方法參數傳遞,而不是將MyWorkFlow類名稱用作WorkFlowEntity參數。 – DwB 2013-04-09 20:03:59