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



是否可以使用反射来创建动态IF语句?

我已经看到了BeanShell的例子(像这样:动态if语句评估问题与字符串比较),但我想知道是否有可能做到没有BeanShell,并指出一些例子,以适应我的需要。

基本上我有一个这样的语句:a操作符b

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

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

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

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

反射不起作用。反射为您提供有关代码结构(类,方法,属性)的信息,但它不允许您更改和更新现有代码。

不要尝试生成新代码,而是尝试添加一种方法,让用户根据他们的输入来改变应用程序的行为。

我不知道你到底想干什么。发布一些用户输入和预期行为的例子,以帮助缩小选择范围。但这里有一些事情可能会帮助你完成你的任务:
  • 有一个用户界面,帮助用户选择操作数的时间,用文本字段表示值,下拉框表示操作符。简单的解决方案,但我不推荐它,因为它可能增加用户界面的复杂性。
  • 为你的表达式写一个解析器。为这种非常简单的语言(a操作符B)编写一个简单的解析器应该可以在合理的时间内完成。
  • 领域特定语言。允许应用程序的用户编写一些脚本,这些脚本由应用程序解释并以某种方式响应。你可以想象一个由简单的比较组成的DSL,其结果将影响你的应用程序的行为。看看Groovy,它是一个很好的语言。

你可以做一个这样的界面

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

你可以准备一个包含所有可用操作符的列表并对其进行迭代,甚至可以在属性文件中配置操作符列表

最新更新