如何创建动态IF语句?反射?

时间:2011-09-14 14:48:38

标签: java reflection dynamic if-statement

是否可以通过反射创建动态IF语句?

我见过BeanShell的例子(像这样:Dynamic if statement evaluation problem with string comparison)但是我想知道是否可以在没有BeanShell的情况下做到这一点,并指出一些例子来适应我的需要。

基本上我有一份表格声明:A运营商B.

A和B可以是数字(双打或整数)或字符串,但总是A与B的类型相同。 运算符可以是!=,==,> =,>,< =,<,甚至其他行为可以通过他们自己的类定义,另一个原因我将使用反射,因为我可以采取该字符串并使用反射来调用适当的方法。

我希望(必须)避免分支“if”和“switch”,因为变化太多,并且会随着用户生成的输入而不断变化。

3 个答案:

答案 0 :(得分:3)

您可以创建一个工厂,为给定的输入返回正确的运算符。

public class OperatorFactory {
  private static final Map<String, Operator<?>> OPERATORS = new HashMap<String, Operator<?>>();

  static {
    OPERATORS.put("<Number", new LessThanNumOperator());
    OPERATORS.put("==Number", new EqualToNumOperator());
    OPERATORS.put("<String", new LessThanStringOperator());
    ...
  }

  public static Operator<?> getOperator(String someUserSpecifiedOp, Class<?> paramType) {
    String key = someUserSpecifiedOp;
    if (Number.class.isAssignableFrom(paramType)) {
      key += "Number";
    } else if (String.class.isAssignableFrom(paramType)) {
      key += "String";
    }
    return OPERATORS.get(key);
  }
}

public interface Operator<T> {
  public boolean execute(T lhs, T rhs);
}

public class LessThanNumOperator implements Operator<Number> {
  public boolean execute(Number lhs, Number rhs) {
     return  lhs.doubleValue() < rhs.doubleValue();
  }
}

然后使用它:

OperatorFactory.getOperator(userDesignatedOperation, lhs.getClass()).execute(lhs, rhs);

答案 1 :(得分:1)

你可以制作这样的界面

public interface MyComparator
{
    public boolean matches(String operator);
    public boolean compare(String a, String b);
}

然后你可以创建你想要实现这个界面的多少个类

public class MyEquals implements MyComparator
{
    @Override
    public boolean matches(String operator)
    {
    return "==".equals(operator);
    }

    @Override
    public boolean compare(String a, String b)
    {
    return a.equals(b);
    }
}

并像这样加载它们:

Class compClass = Class.forName(classname);
MyComparator comp = (MyComparator)compClass.newInstance();

你可以准备一份所有可用运算符的列表并迭代它,甚至在属性文件上配置运算符列表。

答案 2 :(得分:1)

反思无济于事。 Reflection为您提供有关代码结构(类,方法,属性)的信息,但它不允许您更改和更新现有代码。

请勿尝试生成新代码,请尝试为用户添加更改应用行为的方式,具体取决于他们的输入。

我不知道你到底想要做什么。发布一些用户输入和预期行为的示例,以帮助缩小选项范围。但是这里有一些可以帮助你完成任务的事情:

  • 有一个用户界面,可以帮助您的用户选择操作数的时间,文本字段为值,以及操作员的下拉框。简单的解决方案,但我不推荐它,因为它可能会增加用户界面的复杂性。
  • 为表达式编写解析器。为这种非常简单的语言(A运算符B)编写一个简单的解析器应该在合理的时间内完成。
  • 域特定语言。允许应用程序的用户编写一些由应用程序解释并以某种方式响应的脚本。您可以想象DSL包含简单的比较,结果将影响您的应用程序的行为。看看Groovy,它是这个用例的好语言。