Как присвоить значение примитивного типа аргументам метода с использованием отражения Java?

#java #reflection #java-8

#java #отражение #java-8

Вопрос:

Я новичок в концепции отражения Java. Мне нужно получить доступ к одному методу из определенного класса, используя отражение Java. Этот метод имеет три разных типа аргументов, подобных этому,

 public void print(int start, String middle, int end) {
   System.out.println(start);
   System.out.println(middle);
   System.out.println(end);
}
  

Я попытался вызвать этот метод следующим образом,

 ...
method.invoke(null, "middle", null);
...
  

Я получил исключение IllegalArgumentException. Я знаю, что значение null приемлемо для аргументов типа оболочки, но я просто попробовал этот метод, чтобы узнать, как он работает.

Итак, мой главный вопрос: как передать значение примитивного типа этому аргументу метода через отражение? кроме того, как передать значение по умолчанию для аргументов примитивного типа через отражение? (например: предположим, мне не нужно значение end arg во время выполнения, тогда как передать 0 для end arg)

Есть ли какой-либо способ решить эту проблему?

Комментарии:

1. Не могли бы вы поделиться полным stracktrace?

2. Примитивный тип не может быть null . Если вы хотите использовать null в качестве параметра, вам придется изменить значение int на Integer .

3. Передайте an Integer ; вероятно, вы также можете просто передать int значение и позволить автоматической блокировке автоматически превратить его в an Integer . Так что, если бы вы вызвали print(0,"xxx",1) , просто используйте printMethod.invoke(0,"xxx",1) или printMethod.invoke(Integer.valueOf(0), "xxx", Integer.valueOf(1))

4. Ваша проблема не имеет ничего общего с примитивными типами. Поскольку этого метода нет static , вы должны предоставить объект для вызова метода, так же просто, как method.invoke(object, 100, "middle", 42) . Даже для static методов необходим первый аргумент, как и сигнатура метода invoke​(Object obj, Object... args) , поэтому вам придется вставлять a null в начале для static методов, за которыми следуют аргументы метода.

Ответ №1:

Предположим, что у вас есть этот класс:

 public class SomeClass {

    public void print(int start, String middle, int end) {
        System.out.println(start);
        System.out.println(middle);
        System.out.println(end);
    }

}
  

Вы можете использовать следующий код, чтобы:

  1. Создайте экземпляр класса с помощью отражения
  2. Извлеките нужный метод
  3. Вызовите нужный метод, используя отражение
 public class SomeOtherClass {

    public static void main(String... args) {
    try {
        var instance = Class
        .forName(SomeClass.class.getName())
        .getConstructor()
        .newInstance();
        var printMethod = SomeClass.class.getMethod("print", int.class, String.class, int.class);
        printMethod.invoke(instance, 0, "it's me", 0);
    } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
        System.err.println("An error has occurred while accessing method");
        e.printStackTrace();
    }
    }

}
  

Обратите внимание, что для примитивных значений нет необходимости передавать is null . В этих случаях вам необходимо указать значение, что, в свою очередь, означает рефлективный вызов метода следующим образом:

printMethod.invoke(instance, 0, "it's me", 0);

Обратите внимание, что это будет то же самое, что и прямой вызов метода, так как в этом случае попытка передать в null качестве аргумента метода целые числа приведет к ошибке компиляции.

Комментарии:

1. Привет, @akortex91 . Спасибо за ответ. В этом примере вы получаете и вызываете метод напрямую, используя имя метода. Но в моем случае класс имеет список методов, я получаю этот конкретный метод, используя имя метода. Предположим, что у конкретного метода есть 3 аргумента, но у меня есть только 2 значения. Я попробовал этот код Object[] input = new Object[method.getParameterCount()]; method.invoke(cls.newInstance(), input); В этом случае, давайте предположим, что входной массив выглядит следующим образом после вставки 2 значений [1, "hi"]; , тогда какой тип значения мне нужно передать для 3-го аргумента?