是否可以使用反射来创建动态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();
你可以准备一个包含所有可用操作符的列表并对其进行迭代,甚至可以在属性文件中配置操作符列表