How to create instance with a constructor chosen by the user?
I have been working to better understand Java's reflection tools, and am now trying to create a new instance of a class with a constructor that has been chosen by the user in a drop-down-box.
//ask user what to name the new instance of chosen Class ( passed into this method )
String instanceName = JOptionPane.showInputDialog(null, "Under what name would you like to store this Instance?",
"Create an Instance of a Class", JOptionPane.QUESTION_MESSAGE);
Object chosenC = JOptionPane.showInputDialog(null, "Please choose a Constructor for" + chosenClass,
"Create an Instance of a Class", 3, null, getConstructors(chosenClass), JOptionPane.QUESTION_MESSAGE);
Constructor开发者_C百科 c = (Constructor)chosenC;
Class[] params = c.getParameterTypes(); //get the parameters of the chosen Constructor
try {
//create the instance with the correct constructor
instance = c.newInstance((Object[])params);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e){
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Right now, I get an ArgumentTypeMismatch Exception if I select anything but the default constructor(no parameters). Am I missing something blatantly obvious?
Thank you for any help.
EDIT Thank you all for your answers.
But then how would I ask for the parameters? If I get the length of the params array, then I would have to determine what type of class each index was and ask the user to input a value in the correct form? Then how would I pass that new array into the newInstance parameter?
Given a class with a constructor like so:
MyClass(String s, Long l)
Your code is actually invoking the following:
new MyClass(String.class, Long.class)
Where it should be invoking:
new MyClass("", 1L)
You need an instance of each of the constructor parameter types, but you're only passing classes. Interestingly, if you constructor only takes instances of Class
, it would work, but would give unexpected results.
You are passing a Class[] to the constructor, when you want an array of instances. For example, if your constructor is Foo(String), you want to do something like
c.newInstance(new Object[] {"aString"});
What you are doing is,
c.newInstance(new Object[] {String.class});
Your params
need to be the arguments passed to the constructor. Your params are all Class references so unless all your parameters are Class a, Class b, Class c
This won't work.
Perhaps you should allow the user to determine what the values should be.
The call to:
instance = c.newInstance((Object[])params);
here you have to pass in the arguments for the constructor and not the types that you get with the call:
Class[] params = c.getParameterTypes();
If your constructor is:
public MyConstructor( int foo, String bar ) {
//...
}
then you should pass in params as (e.g.):
Object [] params = new Object [] { 10, "someString" };
When you call newInstance
on the Constructor instance, you need to pass parameters of the correct classes. You are supplying the Class
objects themselves as parameters.
For instance, if your constructor is
Person(String firstName, String lastName)
You would call
new Person("John", "Doe");
Or, in reflection terms
c.newInstance("John", "Doe");
But your code is in fact doing
c.newInstance(String.class, String.class);
If you want the user to select a constructor, you will need to ask him for some parameters as well.
精彩评论