如何在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"]
答案 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)以确保您在类数据成员中有值。同样,这不是一个好的编程实践,但它可以满足您的需求。