org.apache.commons.beanutils.MethodUtils.invokeMethod给出java.lang.NullPointerException

时间:2011-08-03 09:07:39

标签: java apache-commons

我正在使用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 个答案:

答案 0 :(得分:4)

我希望简短的回答是您无法提供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() - 如果你传入null,那么就是一个NPE。


编辑:我正在假设您打算调用invokeMethod(Object object, String methodName, Object arg)方法 - 这确实会出现上述问题。在下面的Adam的评论之后,您似乎很可能想要调用我认为在这种情况下会起作用的invokeMethod(Object object, String methodName, Object[] args)方法。

在这种情况下,您的问题是由编译器的类型推断和方法签名解析引起的。 null字面值可以表示任何非基本类型,因此它可以适用于ObjectObject[],同时不代表其中任何一个。{1}}或null。由于这一点(以及我不是100%确定的规范的某些部分),编译器会将您的Object解释为String value = (String) MethodUtils.invokeMethod(o, "getValue", (Object[])null); 并调用该方法,并带有上述后果。

如果您的代码包含足够的信息以将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();
    }
}

但是使用标准reflection,这可能相对简单,甚至更清晰:

{{1}}

答案 1 :(得分:0)

为什么不使用

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

使用null第三个参数

没有异常