在java方法中获取return语句

时间:2013-08-15 20:39:37

标签: java

如何在java中获取方法的所有可能返回值?

示例:

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

 if (condition2) {
    return "b";
 }

 if (condition3) {
     return "c";
 } 

}

我需要这样的东西:

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

7 个答案:

答案 0 :(得分:5)

您可以检索方法签名,在这种情况下,该签名将是Object作为返回类型。

要获取更多详细信息,您需要静态分析源代码或返回类型enum

答案 1 :(得分:4)

如果您只需要分析返回常量值的简单方法(例如示例中的方法),那么您可以通过使用ASM或类似字节码工具包的静态分析来相对轻松地完成此操作。

对于匹配示例结构的方法(即只直接返回常量),您只需要查找模式

LDC ???
ARETURN

收集加载LDC的常数。这将非常简单。

如果方法可能更复杂,例如,如果它们返回分配给变量的值,则需要执行流分析。这是更多的工作,但ASM提供支持。

如果您正在分析的方法返回的值不是简单常量,那么通过静态分析来完成这项工作将非常困难/不可能。

答案 2 :(得分:1)

你不能用Java做这样的事情,但你可以这样做:

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();

}

然后:

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

答案 3 :(得分:1)

正如@Johan所说,这是不可能的。如果你确实需要它,唯一的方法是将这些可能的结果存储在Map中,将方法名称映射到List或数组,或者更好的是,如果可能的话,使用枚举。

编辑:

阅读完评论后,我认为您应该使用HashMap,其中Node作为键,List作为值。分析节点时,在列表中创建退出节点列表,然后将该列表映射到节点。

答案 4 :(得分:1)

首先删除多个退货:

另外,要获取所有返回类型,只需将对象List传递给方法,然后更改onEvent代码,如下所示:

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;
}

像这样打电话给onEvent:

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

答案 5 :(得分:0)

使用命令模式和enum有一种解决方法。

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();
    }
}

答案 6 :(得分:-1)

它不是很好的编程习惯,但是您可以创建一个包含3个公共数据成员的类,并使您的代码看起来像这样。 (我称之为“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
 }

然后你需要另一种控制结构来表达某些东西 if(myclass.datamember!= null)以确保您在类数据成员中有值。同样,这不是一个好的编程实践,但它可以满足您的需求。