having problems factory class, pass in human readable name maps class has single constructor single argument, following error:
java.lang.nosuchmethodexception: com.satgraf.evolution2.observers.vsidstemporallocalityevolutionobserver.<init>(com.satlib.evolution.concreteevolutiongraph) @ java.lang.class.getconstructor0(class.java:2892) @ java.lang.class.getconstructor(class.java:1723) @ com.satlib.evolution.observers.evolutionobserverfactory.getbyname(evolutionobserverfactory.java:84) @ com.satgraf.evolution2.ui.evolution2graphframe.main(evolution2graphframe.java:229)
these classes in question, have dozen of these things in different projects, work without problem - including 1 identical, can't see why 1 failing:
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 = 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; } } }
the class being instantiated is:
public class vsidstemporallocalityevolutionobserver extends jpanel implements evolutionobserver{ public vsidstemporallocalityevolutionobserver(evolutiongraph graph){ ... } ... }
the argument graph
of type:
public class concreteevolutiongraph extends concretecommunitygraph implements evolutiongraph{ ... }
getconstructor
requires exact match on parameter types; not attempt find 'compatible' constructor. getconstructor
javadoc says "the constructor reflect public constructor of class represented class object formal parameter types match specified parametertypes
." (in current openjdk, getconstructor
delegates to getconstructor0
loops through constructors , compares given parameter array against constructor.getparametertypes()
.)
at runtime, code looks constructor taking parameter of type concreteevolutiongraph
(graph.getclass()
returns graph
's runtime type), , vsidstemporallocalityevolutionobserver
doesn't have one.
if you're looking constructor taking evolutiongraph
, pass evolutiongraph.class
getconstructor
instead. if instead want constructor called graph's runtime type, you'll need manually loop on result of getconstructors()
looking single-argument constructor graph.getclass().isassignableto(ctor.getparametertypes()[0])
. note there may more one, , when interfaces involved, there may not most-specific one. you'll have decide how break ties.