我一直在努力更好地理解Java的反射工具,现在我正在尝试使用用户在下拉框中选择的构造函数创建一个类的新实例。
//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 = (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();
}
现在,如果我选择除默认构造函数(无参数)之外的任何内容,我会得到一个ArgumentTypeMismatch异常。我错过了一些明显的东西吗?
感谢您的帮助。
修改 谢谢大家的答案。
但那我怎么要求参数?如果我得到params数组的长度,那么我必须确定每个索引是什么类型的类,并要求用户以正确的形式输入值?那么我如何将新数组传递给newInstance参数?
答案 0 :(得分:3)
给定一个带有类似构造函数的类:
MyClass(String s, Long l)
您的代码实际上是在调用以下内容:
new MyClass(String.class, Long.class)
它应该在哪里调用:
new MyClass("", 1L)
您需要每个构造函数参数类型的实例,但是您只传递类。有趣的是,如果构造函数只接受Class
的实例,那么它会起作用,但会产生意想不到的结果。
答案 1 :(得分:1)
当您需要一组实例时,您正在将Class []传递给构造函数。例如,如果构造函数是Foo(String),则需要执行类似
的操作c.newInstance(new Object[] {"aString"});
你在做什么,
c.newInstance(new Object[] {String.class});
答案 2 :(得分:1)
您的params
需要是传递给构造函数的参数。你的参数都是类引用,所以除非你的所有参数都是Class a, Class b, Class c
这不起作用。
也许您应该允许用户确定值应该是什么。
答案 3 :(得分:1)
致电:
instance = c.newInstance((Object[])params);
这里你必须传递构造函数的参数,而不是传递调用的类型:
Class[] params = c.getParameterTypes();
如果你的构造函数是:
public MyConstructor( int foo, String bar ) {
//...
}
然后你应该传递params作为(例如):
Object [] params = new Object [] { 10, "someString" };
答案 4 :(得分:1)
在构造函数实例上调用newInstance
时,需要传递正确类的参数。您将Class
个对象本身作为参数提供。
例如,如果你的构造函数是
Person(String firstName, String lastName)
你会打电话给
new Person("John", "Doe");
或者,用反思术语
c.newInstance("John", "Doe");
但你的代码实际上在做
c.newInstance(String.class, String.class);
如果您希望用户选择构造函数,您还需要询问他一些参数。