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
精彩评论