越来越显示java.lang.NullPointerException调用Method.invoke时 [英] Getting java.lang.NullPointerException when calling Method.invoke

查看:1734
本文介绍了越来越显示java.lang.NullPointerException调用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的());

演示上ideone

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

Demo on ideone.

这篇关于越来越显示java.lang.NullPointerException调用Method.invoke时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆