![](/img/trans.png)
[英]Java: Method.invoke (this, args) NullPointerException
[英]Getting java.lang.NullPointerException when calling Method.invoke
我正在按照Java annotaitons这个教程进行操作,并实现了Test annotation,如图所示。 但是在运行代码时,我得到以下输出。
java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at TestAnnotationParser.parse(Demo.java:24)
at Demo.main(Demo.java:51)
Passed:0 Fail:1
以下是我的代码。 有人可以指出我的错误吗?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test {
Class expected();
}
class TestAnnotationParser {
public void parse(Class<?> clazz) throws Exception {
Method[] methods = clazz.getMethods();
int pass = 0;
int fail = 0;
for (Method method : methods) {
if (method.isAnnotationPresent(Test.class)) {
Test test = method.getAnnotation(Test.class);
Class expected = test.expected();
try {
method.invoke(null);
pass++;
} catch (Exception e) {
if (Exception.class != expected) {
e.printStackTrace();
fail++;
} else {
pass++;
}
}
}
}
System.out.println("Passed:" + pass + " Fail:" + fail);
}
}
class MyTest {
@Test(expected = RuntimeException.class)
public void testBlah() {
}
}
public class Demo {
public static void main(String[] args) {
TestAnnotationParser parser = new TestAnnotationParser();
try {
parser.parse(MyTest.class);
} catch (Exception e) {
e.printStackTrace();
}
}
}
传递给invoke
的参数必须是调用该方法的对象,除非该方法是static
。 你通过反思做了什么相当于:
MyTest obj = null;
obj.testBlah();
当然,有一个NPE。 要解决此问题,请传递要调用该方法的对象,或使该方法保持static
。
这是一种修复方法:
public <T> void parse(Class<T> clazz, T obj) throws Exception {
Method[] methods = clazz.getMethods();
int pass = 0;
int fail = 0;
for (Method method : methods) {
if (method.isAnnotationPresent(Test.class)) {
Test test = method.getAnnotation(Test.class);
Class expected = test.expected();
try {
method.invoke(obj);
pass++;
} catch (Exception e) {
if (Exception.class != expected) {
e.printStackTrace();
fail++;
} else {
pass++;
}
}
}
}
System.out.println("Passed:" + pass + " Fail:" + fail);
}
...
parser.parse(MyTest.class, new MyTest());
Method#invoke有你问题的答案:
public Object invoke(Object obj,
Object... args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
抛出: NullPointerException
- 如果指定的对象为null且方法是实例方法。
这个问题在这里:
method.invoke(null);
此方法的第一个参数是调用方法的对象。 这是类似这样的动态(反射)等价物:
Object foo = null;
foo.toString();
当然,我们希望此代码提供NullPointerException
因为foo
为null
。
问题是您正在将null目标对象传递给method.invoke(object)
方法。 目标对象不应为null,否则需要nullpointerexception。
调用方法有以下用法:
Method.invoke(targetObject, args1, args2, args3...); where args1, args2, args3 etc are argument to the method being invoked.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.