简体   繁体   中英

Java: Method.invoke (this, args) NullPointerException

I posted this this question, which basically amounts to an attempt to map Strings to functions in Java. I am trying to solve it by creating a HashMap <String, Method> , but every time I try to run Method.invoke (this, args), where args is an array of Objects corresponding to the parameters of Method, I get a NullPointerException . I declare the Methods in my HashMap as follows: mypackage.MyClass.class.getMethod ("methodName", args) , where args is an array of Class object corresponding to the parameters of methodName . I've been working on this for a couple of hours and I'm starting to get really frustrated. If anyone has any suggestions I would really appreciate it!

HashMap <String, Method> myMethods = new HashMap <String, Method> (); 
Class [] args = {param1.class, param2.class, param3.class}; 
myMethods.put ("aKey", mypackage.MyClass.class.getMethod ("aMethod", args)); 
Method thisTest = myTests.get (thisKey);
Object [] args1 = {param1, param2, param3};
String thisResult = (String) thisTest.invoke (this, args1); // NPE occurs in this line

Aug 14, 2012 10:37:36 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
        at mypackage.MyClass.myMethod (MyClass.java:61)
        at org.apache.jsp.myMethod_jsp._jspService(getZabbix_jsp.java:70)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
        at java.lang.Thread.run(Unknown Source)

You need to be REALLY careful when dealing with reflection.

The Class parameters MUST be an exact match to the method declaration you are searching for.

For example if you have a method that takes an interface of MyAwesomeInterface and you implement that interface in your MyAwesomeImplementation , you can't use the class reference of MyAwesomeImplementation when you look up the method.

For example

getClass().getMethod("doAwesomeness", new Class[] {MyAwesomeImplementation.class});

Won't work. It requires MyAwesomeInterface.class

I put this little example together and it works fine

public String methodToBeInvoked(String value, int iValue) {

    return "You said " + value + " with " + iValue;

}

public MethodInvocation() {

    Map<String, Method> myMethods = new HashMap<String, Method>(25);
    try {

        Method method = getClass().getMethod("methodToBeInvoked", new Class[]{String.class, int.class});

        myMethods.put("invoke", method);

        System.out.println(myMethods.get("invoke").invoke(this, "Hello", 100));

    } catch (Exception exp) {

        exp.printStackTrace();

    }
}

I suspect that the class parameters you are using to look up the method do not match the method declarations.

Make sure the method is not null when you look it up & when you try & pull it from the map, it'll help narrow down the problem

Although the population of myTests Map is not shown, it obviously doesn't contain the test method thisTest resulting in an NPE.

The first thing to do here is to inspect the contents of this Map to ensure that it contains the requested key.

Also, it's worth having a guard clause on thisTest before you attempt to invoke the method to prevent it blowing up.

This line can only produce a NPE in case thisResult is null, which in turn means thisKey is not initialized in myTests. Use "aKey" instead of thisKey and it should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM