Java: Как использовать не примитивные типы для constructor.newInstance () в Java Reflection? - PullRequest
3 голосов
/ 28 ноября 2010

После долгого дня поиска я все еще не могу понять, как я могу создать новый объект из самодельного класса, если конструктор принимает не примитивные аргументы. Теперь я начинаю сомневаться, возможно ли это вообще?!

В Документации отражения они говорят только о примитивных типах (таких как int, float, boolean и т. Д.), Насколько я видел. И вся остальная информация / сайт / мастерская / пример, которую я нашел, также просто учитывает примитивные типы, чтобы найти конструктор и создать новый экземпляр.

Итак, что я хочу сделать, это следующее (разбитый сценарий):

Предположим, я получил класс с именем MyStupidClass. Другой класс (назовем его MyUsingClass) принимает объект MyStupidClass в качестве аргумента в конструкторе. Теперь в моем основном приложении я хочу иметь возможность загрузить класс MyUsingClass и создать экземпляр объекта из конструктора.

Это то, что я узнал об «использовании Reflection»:

С пустым конструктором:

//the MyUsingClass:
public class MyUsingClass {

   //the public (empty) constructor
   public MyUsingClass() {
      ...
   }
}

В основном приложении я бы сейчас сделал что-то вроде:

//get the reflection of the MyUsingClass
Class<?> myUsingClassClass = Class.forName("MyUsingClass");
//get the constructor [I use getConstructor() instead of getConstructors(...) here as I know there is only one]
Constructor<?> myUsingClassConstr = myUsingClassClass.getConstructor();
//instanciate the object through the constructor
Object myInstance = myUsingClassConstr.newInstance(null);

Теперь, если бы я использовал некоторые примитивные типы в MyUsingClass , это выглядело бы примерно так:

//the MyUsingClass:
public class MyUsingClass {

   //the public (primitive-only) constructor
   public MyUsingClass(String a, int b) {
      ...
   }
}

В основном приложении последняя строка изменится на что-то вроде:

//instanciate the object through the constructor
Object myInstance = myUsingClassConstr.newInstance(new Object[]{new String("abc"), new Integer(5)});

Пока проблем нет (в приведенном выше коде могут быть небольшие ошибки, так как это всего лишь разбитый пример ...) Теперь ключевой вопрос в том, как мне создать myInstance, если MyUsingClass выглядит примерно так:

//the MyUsingClass:
public class MyUsingClass {

   //the public (primitive-only) constructor
   public MyUsingClass(String a, int b, MyStupidObject toto) {
      ...
   }
}

? Любая помощь будет оценена! Спасибо, что прочитали мой вопрос!

приветствует св

Ответы [ 3 ]

13 голосов
/ 28 ноября 2010

Нет проблем. Много лет назад я тоже потратил много времени на эту вещь.

  1. Вы можете использовать Class.newInstance(), только если вы вызываете конструктор по умолчанию.
  2. Во всех других случаях вы должны сначала найти подходящий конструктор, вызвав getConstructor() и вызвав его newInstance().
  3. При вызове getConstructor() используйте int.class, long.class, boolean.class, и т. Д. для примитивов. Если у вашего класса Foo есть конструктор Foo(int p), вы должны сказать

    Constructor c = Foo.class.getConstructor(int.class);

  4. Как только вы получите конструктор, вызовите его с помощью newInstance ():

    c.newInstance(12345);

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

`c.newInstance(new Object[] {12345, "foo", true})`

Обратите внимание, что с java 5 нам повезло с автобоксом. Для версий до 5 нам пришлось использовать более подробный синтаксис:

`c.newInstance(new Object[] {new Integer(12345), "foo", new Boolean(true)})`

т.е. мы использовали int.class для поиска конструктора и тип Integer для его вызова.

Надеюсь, это поможет.

1 голос
/ 28 ноября 2010

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

Object myInstance = myUsingClassConstr.newInstance(new Object[] {
    new String("abc"),
    new Integer(5),
    new MyStupidObject()
});

Из Constructor.newInstance документации :

Использует конструктор, представленный этим объектом Constructor, для создания и инициализации нового экземпляра декларирующего класса конструктора с указанными параметрами инициализации. Отдельные параметры автоматически развертываются, чтобы соответствовать примитивным формальным параметрам, а примитивные и опорные параметры при необходимости подвергаются преобразованиям вызова метода.

Ссылочные типы конкретно перечислены там и не требуют специальной обработки.

0 голосов
/ 29 ноября 2010

Хорошо, это (все ответы) мне очень помогли. Это работает сейчас, по крайней мере, на первый взгляд. Потребуются дальнейшие испытания, но я надеюсь, что теперь я справлюсь с этим один!

Большое спасибо ...

[Они могут быть более конкретными по этой теме в спецификациях, хотя]

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