简体   繁体   English

调用Method.invoke时获取java.lang.NullPointerException

[英]Getting java.lang.NullPointerException when calling Method.invoke

I'm following this tutorial on Java annotaitons and implemented the Test annotation as shown there. 我正在按照Java annotaitons这个教程进行操作,并实现了Test annotation,如图所示。 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 . 传递给invoke的参数必须是调用该方法的对象,除非该方法是static What you did through reflection is equivalent to this: 你通过反思做了什么相当于:

MyTest obj = null;
obj.testBlah();

Naturally, there's an NPE. 当然,有一个NPE。 To fix this problem, pass an object on which to invoke the method, or make the method static . 要解决此问题,请传递要调用该方法的对象,或使该方法保持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 . 在ideone上演示

The Method#invoke has the answer to your question: Method#invoke有你问题的答案:

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且方法是实例方法。

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因为foonull

The problem is that you are passing a null target object to method.invoke(object) method. 问题是您正在将null目标对象传递给method.invoke(object)方法。 The target object should not be null, else a nullpointerexception is expected. 目标对象不应为null,否则需要nullpointerexception。

The invoke method has below usages: 调用方法有以下用法:

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.

相关问题 Java:Method.invoke(this,args)NullPointerException - Java: Method.invoke (this, args) NullPointerException java.lang.NullPointerException:无法在 null 上调用方法 get() object - java.lang.NullPointerException: Cannot invoke method get() on null object Android Studio java.lang.NullPointerException:尝试调用虚拟方法 - Android Studio java.lang.NullPointerException: Attempt to invoke virtual method TabLayout 中的“java.lang.NullPointerException:尝试调用虚拟方法” - “java.lang.NullPointerException: Attempt to invoke virtual method” in TabLayout Android + java.lang.NullPointerException:尝试调用接口方法 - Android + java.lang.NullPointerException: Attempt to invoke interface method java.lang.NullPointerException:无法在空对象上调用方法queryForList() - java.lang.NullPointerException: Cannot invoke method queryForList() on null object java.lang.NullPointerException:尝试调用虚拟方法+ Firebase - java.lang.NullPointerException: Attempt to invoke virtual method + Firebase 如何解决“java.lang.NullPointerException:无法调用方法 startsWith()”? - How to resolve "java.lang.NullPointerException: Cannot invoke method startsWith()"? Java、Selenium 和 Method.invoke():获取 NoSuchMethodException - Java, Selenium, and Method.invoke(): Getting NoSuchMethodException 从 groovy 脚本调用方法时,我在 Jenkisn 上收到 java.lang.NullPointerException - I am getting java.lang.NullPointerException on Jenkisn while calling method from groovy script
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM