iberck
iberck

Reputation: 2430

Get return statements in a java method

How can I get all possible return values of a method in java?

Example:

Object onEvent() {
 if (condition) {
     return "a";
 }

 if (condition2) {
    return "b";
 }

 if (condition3) {
     return "c";
 } 

}

I need something like this:

String[] returns = Utils.getReturnStatements("object.onEvent()");
returns = ["a", "b", "c"]

Upvotes: 5

Views: 5920

Answers (7)

Gavin Perkins
Gavin Perkins

Reputation: 693

Its not really good programming practice, but you can create a class with 3 public data members, and have your code look something like this. (Ill call the class "myclass")

public a, b, c = null;

//And then your main class would look something like this
if (condition){
  myclass.a=whatever;
}
else if (condition){
  myclass.b=whatever;
}
else if (condition){
  myclass.c=whatever
 }

Then you would need another control structure that said something along the lines of if (myclass.datamember!=null) to make sure you have values in the class data members. Again, this is not good programming practice, but it will work for what you want.

Upvotes: -1

henry
henry

Reputation: 6096

If you only need to analyse simple methods that return constant values such as the one in your example, then you can do this relatively easily via a static analysis using ASM or a similar bytecode toolkit.

For methods matching the structure of your example (i.e that only directly return constants) you just need to look for the pattern

LDC ???
ARETURN

And collect the constants loaded with LDC. This would be very straightforward.

If the methods can be more complex, e.g if they return values assigned to variables, then you will need to perform a flow analysis. This is much more work, but ASM provides support.

If the methods you are analysing return values other than simple constants then it will be incredibly difficult/impossible to do this via static analysis.

Upvotes: 4

mike
mike

Reputation: 5055

With use of the command pattern and enum there is a workaround.

public class OnEvent implements Command<EventInfo> {

    @Override
    public EventInfo execute() {
        // do some checking
        return EventInfo.A;
    }

    @Override
    public EventInfo[] getValues() {
        return EventInfo.values();
    }


    public static void main(String[] args) {
        OnEvent e = new OnEvent();
        EventInfo retVal = e.execute();
        EventInfo[] values = Utils.getReturnStatements(e);
    }

}

enum EventInfo {
    A, B, C;
}

interface Command<TYPE extends Enum<?>> extends KnownReturnValues<TYPE> { public TYPE execute(); }

interface KnownReturnValues<TYPE> { public TYPE[] getValues(); }

class Utils {

    private Utils() {}

    public static <TYPE extends Enum<?>> TYPE[] getReturnStatements(Command<TYPE> c) {
        return c.getValues();
    }
}

Upvotes: 0

Matthieu
Matthieu

Reputation: 3098

As @Johan said, it is not possible. The only way if you really need it would be for you to store these possible results in a Map mapping the method name to a List or array, or better, use an enum if possible.

Edit:

After reading your comment, I think you should use a HashMap with a Node as the key and a List as value. When you analyse a Node you create the list of exit Nodes in a list, and then map that list to the node.

Upvotes: 1

anubhava
anubhava

Reputation: 785058

First remove multiple returns:

Also to get all return types just pass a List of object to your method and change the onEvent code like this:

Object onEvent(List<Object> rets) {
 String ret = "";
 rets.add("a");
 rets.add("b");
 rets.add("c");

 if (condition) {
     ret = "a";
 }

 if (condition2) {
    ret = "b";
 }

 if (condition3) {
     ret = "c";
 } 
 return ret;
}

Make a call to onEvent like this:

List<Object> returns = new ArrayList<Object>();
Object retVal = obj.onEvent(returns);

Upvotes: 1

morgano
morgano

Reputation: 17422

You can't do such a thing in Java, but you can do something like this:

Object onEvent() {

    List<String> list = new ArrayList<String>();    

    if (condition) {
        list.add("a");
    }

    if (condition2) {
        list.add("b");
    }

    if (condition3) {
        list.add("c");
    }

    return list.toArray();

}

And then:

String[] returns = (String[])MyObj.onEvent();

Upvotes: 1

Johan Sj&#246;berg
Johan Sj&#246;berg

Reputation: 49187

You can only retrieve the method signature, which in this case would be Object as the return type.

To get the any more details you need to either statically analyze the source code or return a type such as an enum.

Upvotes: 5

Related Questions