org.apache.commons.beanutils.MethodUtils.invokeMethod предоставляет исключение java.lang.NullPointerException - PullRequest
2 голосов
/ 03 августа 2011

Я использую org.apache.commons.beanutils.MethodUtils.invokeMethod. Это дает мне исключение нулевого указателя .

Следующий мой первый класс

package com;

import org.apache.commons.beanutils.MethodUtils;

public class test {

    public static void main(String[] args) {
        test t = new test();
        t.getName();
    }

    void getName() {
        try {
            Class c = Class.forName("com.test1");
            Object o = c.newInstance();
            System.out.println(o);
            String value = (String) MethodUtils.invokeMethod(o, "getValue",null);
            System.out.println("Results from getValue: " + value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Следующий мой класс

package com;

public class test1 {

    public String getValue() {
        return "value";
    }

}

При попытке запустить тест выдает следующую ошибку

    com.test1@1add2dd
    java.lang.NullPointerException
    at org.apache.commons.beanutils.MethodUtils.invokeMethod(MethodUtils.java:167)
    at com.test.getName(test.java:18)
    at com.test.main(test.java:9)

Пожалуйста, помогите

Ответы [ 2 ]

4 голосов
/ 03 августа 2011

Я ожидаю, что короткий ответ таков: вы не можете предоставить 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();
    }
}
0 голосов
/ 21 декабря 2012

почему бы не использовать

String value = (String) MethodUtils.invokeExactMethod(o, "getValue",null);

это не дает исключения с нулевым третьим аргументом

...