调用 Method.invoke 时获取 java.lang.NullPointerException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18802277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting java.lang.NullPointerException when calling Method.invoke
提问by Can't Tell
I'm following this tutorial on Java annotaitonsand implemented the Test annotation as shown there. But when running the code I get the following output.
我正在关注有关 Java annotaitons 的本教程并实现了 Test 注释,如图所示。但是在运行代码时,我得到以下输出。
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
Following is my code. Can someone point out what I have got wrong?
以下是我的代码。有人可以指出我有什么问题吗?
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();
}
}
}
采纳答案by dasblinkenlight
The parameter that you pass to invoke
must be an object on which the method is invoked, unless the method is static
. What you did through reflection is equivalent to this:
您传递给的参数invoke
必须是调用该方法的对象,除非该方法是static
. 你通过反射所做的相当于:
MyTest obj = null;
obj.testBlah();
Naturally, there's an NPE. To fix this problem, pass an object on which to invoke the method, or make the method static
.
当然,有一个 NPE。要解决此问题,请传递一个对象以在其上调用该方法,或创建该方法static
。
Here is one way to make a fix:
这是一种修复方法:
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());
回答by Rob
This issue is here:
这个问题在这里:
method.invoke(null);
This method's first parameter is the object to invoke the method on. This is the dynamic (reflection) equivalent of something like this:
该方法的第一个参数是调用该方法的对象。这是动态(反射)等价物:
Object foo = null;
foo.toString();
Of course we would expect this code to give a NullPointerException
because foo
is null
.
当然,我们希望这段代码给出一个NullPointerException
因为foo
是null
。
回答by Gyanendra Dwivedi
The problem is that you are passing a null target object to method.invoke(object)
method.
The target object should not be null, else a nullpointerexception is expected.
问题是您将空目标对象传递给method.invoke(object)
方法。目标对象不应为空,否则会出现空指针异常。
The invoke method has below usages:
invoke 方法有以下用法:
Method.invoke(targetObject, args1, args2, args3...); where args1, args2, args3 etc are argument to the method being invoked.
Method.invoke(targetObject, args1, args2, args3...); where args1, args2, args3 etc are argument to the method being invoked.
回答by M. Abbas
The Method#invokehas the answer to your question:
该方法#调用有回答你的问题:
public Object invoke(Object obj,
Object... args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
Throws:
NullPointerException
- if the specified object is null and the method is an instance method.
抛出:
NullPointerException
- 如果指定的对象为 null 并且该方法是一个实例方法。