5

I have a question about reflection I am trying to have some kind of eval() method. So i can call for example:

eval("test('woohoo')");

Now I understand the there is no eval method in java but there is reflection. I made the following code:

String s = "test";
Class cl = Class.forName("Main");
Method method = cl.getMethod(s, String.class);
method.invoke(null, "woohoo");

This works perfectly (of course there is a try, catch block around this code). It runs the test method. However I want to call multiple methods who all have different parameters.

I don't know what parameters these are (so not only String.class). But how is this possible? how can I get the parameter types of a method ? I know of the following method:

Class[] parameterTypes = method.getParameterTypes();

But that will return the parameterTypes of the method I just selected! with the following statement:

Method method = cl.getMethod(s, String.class);

Any help would be appreciated !

1
  • The eval method looks like Ruby's eval, so maybe you could look at how JRuby does it. Commented Apr 12, 2010 at 10:24

4 Answers 4

15

You will need to call Class.getMethods() and iterate through them looking for the correct function.

For (Method method : clazz.getMethods()) {
  if (method.getName().equals("...")) {
    ...
  }
}

The reason for this is that there can be multiple methods with the same name and different parameter types (ie the method name is overloaded).

getMethods() returns all the public methods in the class, including those from superclasses. An alternative is Class.getDeclaredMethods(), which returns all methods in that class only.

Sign up to request clarification or add additional context in comments.

4 Comments

You guys are soo fast!..:P thanxs for the help!..the following code works perfectly!: Class cl = Class.forName("Main"); for (Method method : cl.getMethods()){ if(method.getName().equals("test")){ Class[] parameterTypes = method.getParameterTypes(); method.invoke(null, "this is", " so cool!"); } }
(ehm could anybody help with the style ? ) (sorry)
Well i posted some code but the style isn't really good.. But never mind. I will post better code when it is finished (for people who might have the same problem).
I dont think people can edit comments. But have a look at the following link for future reference (or just click the help link next to the comment). meta.stackexchange.com/a/24794/167981
5

You can loop over all methods of a class using:

cls.getMethods(); // gets all public methods (from the whole class hierarchy)

or

cls.getDeclaredMethods(); // get all methods declared by this class

.

for (Method method : cls.getMethods()) {
    // make your checks and calls here
}

Comments

2

You can use getMethods() which returns an array of all methods of a class. Inside the loop you can inspect the parameters of each method.

for(Method m : cl.getMethods()) {
   Class<?>[] params = m.getParameterTypes();
   ...
}

Otherwise you can use getDelcaredMethods() which will allow you to "see" private methods (but not inherited methods). Note that if you want to invoke a private methods you must first apply setAccessible(boolean flag) on it:

for(Method m : cl.getDelcaredMethods()) {
   m.setAccessible(true);
   Class<?>[] params = m.getParameterTypes();
   ...
}

Comments

2

Ok thanxs to all the people who answered my question here the final solution:

import java.lang.reflect.Method;
public class Main {
   public static void main(String[] args){
      String func = "test";
      Object arguments[] = {"this is ", "really cool"};
      try{
         Class cl = Class.forName("Main");
         for (Method method : cl.getMethods()){
            if(method.getName().equals(func)){
               method.invoke(null, arguments);
            }
          }
       } catch (Exception ioe){
          System.out.println(ioe);
       }
    }
  public static void test(String s, String b){
     System.out.println(s+b);
  }
}

2 Comments

A problem with this code is that it is not robust. Various changes to the signature of test will result in exceptions; e.g. if the method is not static, if the number of args is different, it the types of the args are different, if the method is not visible.
yes that is right.. but there is no other way to do this. I need to be able to call functions from a string (this is because I need to be able to setup a socket connection to a java program and then send json that will have the appropriate method name and arguments.) If i take care of my exception handling and have good unittests I think it will be robust enough (or i hope so :P ).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.