Я ожидаю, что короткий ответ таков: вы не можете предоставить null
в качестве третьего аргумента MethodUtils.invokeMethod
.Я объясню, почему я подозреваю, что это так (и Javadocs действительно мог бы упомянуть об этом, если это правда).
MethodUtils почти наверняка представляет собой просто слой вокруг стандартной библиотеки отражений Java,Для поиска метода требуется сигнатура метода в форме имени и классов или аргументов.Это необходимо, поскольку можно переопределить метод:
public void foo(String s) {
System.out.println("Got a string: " + s);
}
public void foo(int i) {
System.out.println("Got an int: " + i);
}
Таким образом, вызов invokeMethod
объединяет несколько шагов вместе, но он все еще должен иметь возможность искать нужный объект java.lang.reflect.Method
.И чтобы сделать это, нужно знать тип аргумента (ов) (похоже, версия, которую вы вызываете, предназначена только для унарных методов).Таким образом, единственный способ, которым я могу видеть, что он способен это сделать, это вызвать arg.getClass()
на объекте, который вы передаете, - и эй presto, NPE, если вы передаете null
.
ПравитьЯ работал с предположением, что вы намеревались вызвать метод invokeMethod(Object object, String methodName, Object arg)
- который действительно показал бы проблемы, описанные выше.После комментария Адама, приведенного ниже, кажется вполне вероятным, что вы хотели вызвать метод invokeMethod(Object object, String methodName, Object[] args)
, который, я считаю, сработал бы в этом случае.
В этом случае ваша проблема вызвана выводом типа компилятора и сигнатурой методаразрешающая способность.Литерал null
может представлять любой не примитивный тип, поэтому он может работать либо с Object
, либо с Object[]
, но в то же время не представлять ни один из них.Из-за этого (и некоторой части спецификации, в которой я не уверен на 100%), компилятор интерпретирует ваш null
как Object
и вызывает этот метод с последствиями, описанными выше.
Youможно было бы избежать этого, если бы ваш код содержал достаточно информации, чтобы идентифицировать ноль как нулевой массив - либо путем приведения:
String value = (String) MethodUtils.invokeMethod(o, "getValue", (Object[])null);
, либо путем присвоения строго типизированной переменной:
Object[] args = null;
String value = (String) MethodUtils.invokeMethod(o, "getValue", args);
Помимо описанных выше исправлений вывода типов, вы можете обойти эту проблему с помощью MethodUtils
, явно предоставив информацию о классе аргументов:
MethodUtils.invokeMethod(o, "getValue", new Object[0], new Class[0]);
, но это будет относительно просто, и, возможно, дажеяснее, используя стандартные отражения :
void getName() {
try {
Class c = Class.forName("com.test1");
Object o = c.newInstance();
System.out.println(o);
// The next two lines replace the MethodUtils call
Method getValueMethod = c.getMethod("getValue");
String value = getValueMethod.invoke(o);
System.out.println("Results from getValue: " + value);
} catch (Exception e) {
e.printStackTrace();
}
}