开发者

org.apache.commons.beanutils.MethodUtils.invokeMethod gives java.lang.NullPointerException

I am using org.apache.commons.beanutils.MethodUtils.invokeMethod. It is giving me Null pointer exception.

Following is my first class

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.test开发者_JAVA百科1");
            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();
        }
    }

Following is my second class

package com;

public class test1 {

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

}

When i try to run test it gives me the following error

    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)

Please help


I expect the short answer is that you can't provide null as the third argument to MethodUtils.invokeMethod. I'll explain why I suspect this is so (and the Javadocs could really do with mentioning this, if true).

MethodUtils is almost certainly just a layer around the standard Java reflection library. This takes a method signature, in the form of a name and the classes or the arguments, in order to look up a method. This is required since one can override a method:

public void foo(String s) {
    System.out.println("Got a string: " + s);
}

public void foo(int i) {
    System.out.println("Got an int: " + i);
}

So the invokeMethod call is bundling a few steps together, but it still needs to be able to look up the right java.lang.reflect.Method object. And in order to do this, it's going to need to know the type of the argument(s) (it looks like the version you're calling is only for unary methods). So the only way I can see it's able to do this, is to call arg.getClass() on the object you pass in - and hey presto, an NPE if you pass in null.


Edit: I was working with the assumption that you intended to call the invokeMethod(Object object, String methodName, Object arg) method - which would indeed exhibit the problems above. After Adam's comment below, it seems quite possible that you wanted to call the invokeMethod(Object object, String methodName, Object[] args) method which I believe would have worked in this case.

In that case your problem is caused by the compiler's type inference and method signature resolution. The null literal can represent any non-primitive type, so it could work for either Object or Object[], while at the same time not representing either of them. Because of this (and some part of the spec that I'm not 100% sure of) the compiler interprets your null as an Object and calls that method, with the consequences outlined above.

You could have avoided this if your code contained sufficient information to identify the null as a null array - either by casting:

String value = (String) MethodUtils.invokeMethod(o, "getValue", (Object[])null);

or by assigning to a strongly-typed variable:

Object[] args = null;
String value = (String) MethodUtils.invokeMethod(o, "getValue", args);

Asides from the type inference fixes above, you can work around this problem with MethodUtils by supplying the arguments' class information explicitly:

MethodUtils.invokeMethod(o, "getValue", new Object[0], new Class[0]);

but this would be relatively straightforward, and perhaps even clearer, using standard reflection:

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();
    }
}


why not using

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

is gives no exception with the null third argument

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜