Class.getConstructor无法找到兼容的构造函数

时间:2015-04-28 00:46:33

标签: java reflection

遇到工厂类的问题,我传入一个人类可读的名称,该名称映射到具有单个构造函数且具有单个参数的类,我收到以下错误:

java.lang.NoSuchMethodException: com.satgraf.evolution2.observers.VSIDSTemporalLocalityEvolutionObserver.<init>(com.satlib.evolution.ConcreteEvolutionGraph)
at java.lang.Class.getConstructor0(Class.java:2892)
at java.lang.Class.getConstructor(Class.java:1723)
at com.satlib.evolution.observers.EvolutionObserverFactory.getByName(EvolutionObserverFactory.java:84)
at com.satgraf.evolution2.UI.Evolution2GraphFrame.main(Evolution2GraphFrame.java:229) 

这些是有问题的课程,我在不同的项目中有大约十几个这样的东西,它们都可以毫无问题地工作 - 包括一个几乎相同的,无法理解为什么这个失败了:

public EvolutionObserver getByName(String name, EvolutionGraph graph){
if(classes.get(name) == null){
  return null;
}
else{
  try {
    Constructor<? extends EvolutionObserver> con = classes.get(name).getConstructor(graph.getClass());
    EvolutionObserver i = con.newInstance(graph);
    observers.add(i);
    return i;
  } 
  catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException | IllegalArgumentException | SecurityException ex) {
    Logger.getLogger(EvolutionObserverFactory.class.getName()).log(Level.SEVERE, null, ex);
    return null;
  }
}
}

正在实例化的类是:

public class VSIDSTemporalLocalityEvolutionObserver extends JPanel implements EvolutionObserver{
    public VSIDSTemporalLocalityEvolutionObserver(EvolutionGraph graph){
    ...
    }
...
}

参数graph的类型为:

public class ConcreteEvolutionGraph extends ConcreteCommunityGraph implements EvolutionGraph{
    ...
}

1 个答案:

答案 0 :(得分:1)

getConstructor要求参数类型完全匹配;它并不试图找到一个兼容的&#39;构造函数。 getConstructor Javadoc简单地说&#34;要反映的构造函数是由此Class对象表示的类的公共构造函数,其形式参数类型与parameterTypes指定的类型匹配。&#34; (在当前的OpenJDK中,getConstructor delegates to getConstructor0 loops through all the constructors and compares the given parameter array针对constructor.getParameterTypes()。)

在运行时,您的代码会查找构造函数,该构造函数采用ConcreteEvolutionGraph类型的参数(graph.getClass()返回graph的运行时类型),而VSIDSTemporalLocalityEvolutionObserver不会#39; t有一个。

如果您真的在寻找使用EvolutionGraph的构造函数,请将EvolutionGraph.class传递给getConstructor。如果您想要任何可以使用图形的运行时类型调用的构造函数,那么您需要手动循环查找getConstructors()的结果,查找{{1}的单参数构造函数}}。注意,可能有多个,并且当涉及接口时,可能没有最具体的接口。你必须决定如何打破关系。