越来越显示java.lang.NullPointerException调用Method.invoke时 [英] Getting java.lang.NullPointerException when calling Method.invoke
问题描述
我按照此关于Java教程annotaitons 并实施测试注释如图中所示。但在运行code我得到以下输出时。
显示java.lang.NullPointerException
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:616)
在TestAnnotationParser.parse(Demo.java:24)
在Demo.main(Demo.java:51)
通过:0失败:1
以下是我的code。有人能指出什么我有错了?
进口java.lang.annotation.ElementType;
进口java.lang.annotation.Retention;
进口java.lang.annotation.RetentionPolicy;
进口java.lang.annotation.Target;
进口的java.lang.reflect.Method;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface测试{
类预期();
}类TestAnnotationParser {
公共无效解析(类<> clazz所)抛出异常{
方法[] =方法clazz.getMethods();
INT通= 0;
INT失败= 0; 对于(方法方法:方法){
如果(method.isAnnotation present(的Test.class)){
测试测试= method.getAnnotation(的Test.class);
预计类= test.expected();
尝试{
method.invoke(NULL);
通过++;
}赶上(例外五){
如果(Exception.class!=预期){
e.printStackTrace();
失败++;
}其他{
通过++;
}
}
}
}
的System.out.println(合格+通+失败:失败+);
}
}类MyTest的{ @Test(预期= RuntimeException.class)
公共无效testBlah(){
}
}公共类演示{
公共静态无效的主要(字串[] args){
TestAnnotationParser分析器=新TestAnnotationParser();
尝试{
parser.parse(MyTest.class);
}赶上(例外五){
e.printStackTrace();
}
}
}
传递给参数调用
必须是在其上调用该方法的对象,除非方法是静态
。你通过反射那样就相当于这样的:
MyTest的OBJ = NULL;
obj.testBlah();
当然,有一个NPE。要解决这个问题,通过在其上调用该方法,否则会使方法的对象静态
。
下面是一种方法,使修复:
公开< T>无效解析(类< T> clazz中,T OBJ)抛出异常{
方法[] =方法clazz.getMethods();
INT通= 0;
INT失败= 0; 对于(方法方法:方法){
如果(method.isAnnotation present(的Test.class)){
测试测试= method.getAnnotation(的Test.class);
预计类= test.expected();
尝试{
method.invoke(OBJ);
通过++;
}赶上(例外五){
如果(Exception.class!=预期){
e.printStackTrace();
失败++;
}其他{
通过++;
}
}
}
}
的System.out.println(合格+通+失败:失败+);
}...parser.parse(MyTest.class,新MyTest的());
I'm following this tutorial on Java annotaitons and implemented the Test annotation as shown there. But when running the code I get the following output.
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();
}
}
}
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:
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
.
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());
这篇关于越来越显示java.lang.NullPointerException调用Method.invoke时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!