Как создать экземпляр с выбранным пользователем конструктором? - PullRequest
0 голосов
/ 04 мая 2011

Я работал над тем, чтобы лучше понять инструменты отражения 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, если я выбираю что-либо, кроме конструктора по умолчанию (без параметров). Я что-то упускаю явно очевидное?

Спасибо за любую помощь.

EDIT Спасибо всем за ваши ответы.

Но тогда как мне спросить параметры? Если я получу длину массива params, мне нужно будет определить, к какому классу относится каждый индекс, и попросить пользователя ввести значение в правильной форме? Тогда как мне передать этот новый массив в параметр newInstance?

Ответы [ 5 ]

3 голосов
/ 04 мая 2011

Учитывая класс с конструктором, подобным этому:

MyClass(String s, Long l)

Ваш код фактически вызывает следующее:

new MyClass(String.class, Long.class)

Где он должен вызываться:

new MyClass("", 1L)

Вам нужен экземпляр каждого из типов параметров конструктора, но вы только передаете классы.Интересно, что если ваш конструктор использует только экземпляры Class, он будет работать, но даст неожиданные результаты.

1 голос
/ 04 мая 2011

Когда вы вызываете newInstance в экземпляре конструктора, вам необходимо передать параметры правильных классов. Вы сами предоставляете Class объекты в качестве параметров.

Например, если ваш конструктор

Person(String firstName, String lastName)

Вы бы позвонили

new Person("John", "Doe");

Или, если подумать

c.newInstance("John", "Doe");

Но ваш код на самом деле делает

c.newInstance(String.class, String.class);

Если вы хотите, чтобы пользователь выбрал конструктор, вам нужно будет также запросить у него некоторые параметры.

1 голос
/ 04 мая 2011

Вызов:

instance = c.newInstance((Object[])params); 

здесь вы должны передать аргументы для конструктора, а не типы, которые вы получите при вызове:

Class[] params = c.getParameterTypes();

Если ваш конструкторэто:

public MyConstructor( int foo, String bar ) {
//...
}

тогда вы должны передать в параметрах как (например):

Object [] params = new Object [] { 10, "someString" };
1 голос
/ 04 мая 2011

Ваши params должны быть аргументами, передаваемыми конструктору.Все ваши параметры - это ссылки на классы, поэтому, если все ваши параметры не равны Class a, Class b, Class c, это не сработает.

Возможно, вы должны позволить пользователю определить, какие значения должны быть.

1 голос
/ 04 мая 2011

Вы передаете Class [] в конструктор, когда вам нужен массив экземпляров. Например, если ваш конструктор Foo (String), вы хотите сделать что-то вроде

c.newInstance(new Object[] {"aString"});

То, что вы делаете,

c.newInstance(new Object[] {String.class});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...