遇到工厂类的问题,我传入一个人类可读的名称,该名称映射到具有单个构造函数且具有单个参数的类,我收到以下错误:
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{
...
}
答案 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}的单参数构造函数}}。注意,可能有多个,并且当涉及接口时,可能没有最具体的接口。你必须决定如何打破关系。