newSpringer
newSpringer

Reputation: 1028

Using Reflections: how to test method

I have been looking at Reflections lately in java and I have come up with a simple example

Reflection.java

 import java.lang.reflect.*;

  public class Reflection{
  }

  public static void main(String args[])
  {
     try {
       Class cls = Class.forName("Method");

        Method methlist[] 
          = cls.getDeclaredMethods();
        for (int i = 0; i < methlist.length;
           i++) {  
           Method m = methlist[i];
           System.out.println("name 
             = " + m.getName());
           System.out.println("decl class = " +
                          m.getDeclaringClass());
           Class pvec[] = m.getParameterTypes();
           for (int j = 0; j < pvec.length; j++)
              System.out.println("
               param #" + j + " " + pvec[j]);
           Class evec[] = m.getExceptionTypes();
           for (int j = 0; j < evec.length; j++)
              System.out.println("exc #" + j 
                + " " + evec[j]);
           System.out.println("return type = " +
                              m.getReturnType());
           System.out.println("-----");
        }
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }
 }

Method.java

 public class Method {
  private int f1(
   Object p, int x) throws NullPointerException
  {
     if (p == null)
        throw new NullPointerException();
     return x;
  }

From the above example i am able to return all the information from Method.java which looks like this

name = f1
decl class = class Method
param #0 class java.lang.Object
param #1 int
exc #0 class java.lang.NullPointerException
return type = int
-----
name = main
decl class = class method1
param #0 class [Ljava.lang.String;
return type = void
-----

But my question is, is there a way to test Method.java from Reflection.java with something like

int x = cls.getMethod("f1", Object = anObject, Integer.TYPE = 2 )
System.out.println(x);

And the console should print out 2 because f1 was passed an object?

Upvotes: 0

Views: 182

Answers (3)

Andreas Dolk
Andreas Dolk

Reputation: 114757

You need to create an instance of Method and invoke the private method f1 with the two parameters. It will return an object. There are a couple of pitfalls in your code, but here's a working solution (Note: I renamed your class Method to MyMethod to avoid a name clash:

Method f1Method = MyMethod.class.getDeclaredMethod("f1", Object.class, int.class);
f1Method.setAccessible(true);
int result = (Integer) f1Method.invoke(new MyMethod(), 
                           new Object[]{new Object(), 2});
System.out.println(result);
  • The method is private so you need to get the declared method and make it accessible
  • The method is not static so we need an instance of MyMethod to invoke the method
  • We pass and receive a java primitive type. int.class is allowed. JavaDoc tells us, that if the value has a primitive type, it is first appropriately wrapped in an object. So we'll receive an instance of Integer.

Upvotes: 1

Robin
Robin

Reputation: 36601

Note: the Method class I refer to is the Method class in the JDK, not the one in your example

You are already capable of finding the Method from the Class object. You can now use the Method#invoke method to invoke the method on a certain object

Upvotes: 0

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81674

Check out the Javadoc for java.lang.reflect.Method. You want the method invoke();

Method m = ...
Object result = m.invoke(objectToCallMethodOn, firstArgument, secondArgument);
int x = ((Integer) result).intValue();

Upvotes: 1

Related Questions