In my program, I register JComponent
classes to my classes that handle them for my purposes (converting their values to setting entries). It looks like this:
InputHandlers.register(InputJTextField.class, javax.swing.JPasswordField.class);
InputHandlers.register(InputJTextField.class, JTextField.class);
InputHandlers.register(InputJCheckBox.class, JCheckBox.class);
...
I save these registered values to Map
and retrieve them later. But for the example above, I have a problem: though javax.swing.JPasswordField.class
is subtype of JTextField.class
, the Class.getDeclaredConstructor
doesn't see it that way.
I made a general example to make this question easier to answer. Consider following classes:
class A {
private final B b;
public A(B b) {
this.b = b;
}
}
class B {}
class C extends B {}
Imagine you want to do this:
A.class.getDeclaredConstructor(C.class);
It will throw java.lang.NoSuchMethodException
even though C
is subtype of B
. Here's the full code:
/**
* Test how Class.getDeclaredConstructor seeks for constructors.
* @author Jakub
*/
public class Constructors {
public static class A {
private final B b;
public A(B b) {
this.b = b;
}
}
public static class B {}
public static class C extends B {}
public static void main(String[] args) //throws Exception
{
/** TRY USING REFLECTION **/
//Make A from B
tryAfromParam(new B());
//Make A from C that is cast to B
tryAfromParam((B)new C());
//Make A from C without casting
tryAfromParam(new C());
}
public static A tryAfromParam(Object param) {
System.out.println("Try to make A from "+param.getClass()+" using A.class.getConstructor(...)");
try {
A a = AfromParam(param);
System.out.println(" Sucess :)");
return a;
} catch (Exception ex) {
System.out.println(" CONSTRUCTOR FAILED: "+ex);
}
return null;
}
public static A AfromParam(Object param) throws Exception {
//Fetch the A's class instance
Class cls = A.class;
//Define constructor parameters
Class[] arguments = new Class[] {
param.getClass()
};
//Try to get the constructor
Constructor<A> c = cls.getConstructor(arguments);
//Try to instantiate A
A a = c.newInstance(param);
//Return result
return a;
}
}
And the question is: How to find constructor compatible with arguments or any of their super types? Note that new A(new C())
is valid, so the reflection should work the same way - generally I want to call the constructor the way Java would call it.
Aucun commentaire:
Enregistrer un commentaire