How to create dynamic IF expressions? reflection?

Is it possible to create a dynamic IF statement using reflection?

I saw BeanShell examples (for example: A dynamic problem with evaluating statements with string matching ), but I would like to know if this can be done without BeanShell, and point out some examples to adapt to my needs.

I basically have an operator of the form: operator B.

A and B can be numbers (paired or integer) or strings, but always A is the same type as B. The operator can be! =, ==,> =,>, <=, <, and even others, whose behavior can be determined through its own class, and another reason I will use reflection, since I can take this line and use reflection to call appropriate method.

I want (should) avoid branching "if" and "switch" because there are too many changes and will constantly change with user input.

+4
source share
3 answers

Reflection will not help. Reflection gives you information about your code structure (classes, methods, attributes), but does not allow you to modify and update existing code.

Do not try to generate new code, try instead of adding a way to change the behavior of your application depending on their input.

I don’t know exactly what you are trying to do. Post some examples of input and expected user behavior to reduce options. But here are a few things that can help you with your task:

  • The user has a user interface that helps the user choose the time for operands, text fields for values, and a drop-down list for the operator. A simple solution, but I would not recommend it, as this can complicate the user interface.
  • Write a parser for your expressions. Writing a simple parser for this very simple language (statement B) should be done in a reasonable amount of time.
  • Languages ​​of the domain. Allows users of your application to write some scripts that are interpreted by your application and react in some way. You can imagine a DSL consisting of simple comparisons, and the results will influence the behavior of your application. Take a look at Groovy, this is a good language for this use case.
+1
source

You can create a factory that returns the correct operator for the given input.

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

And then use it:

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

You can make such an interface

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

Then you can do how many classes you want to implement through this interface.

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

and download them as follows:

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

you could prepare a list of all available statements and iterate over it and even have a list of statements configured in the properties file.

+1
source

All Articles