org.codehaus.janino
public class ExpressionEvaluator extends ScriptEvaluator
The syntax of the expression to compile is that of a JavaTM expression, as defined in the Java Language Specification, 2nd edition, section 15. Notice that a JavaTM expression does not have a concluding semicolon.
Example:
a + 7 * b(Notice that this expression refers to two parameters "a" and "b", as explained below.)
The expression may optionally be preceeded with a sequence of import directives like
import java.text.*; new DecimalFormat("####,###.##").format(10200020.345345)(Notice that the import directive is concluded with a semicolon, while the expression is not.) This feature is not available if you compile many expressions at a time (see below).
The expression evaluator is implemented by creating and compiling a temporary compilation unit defining one class with one static method with one RETURN statement.
To set up an ExpressionEvaluator object, proceed as follows:
(Object[])
). This evaluation is
very fast, compared to the compilation.
Less common methods exist that allow for the specification of the name of the generated class, the class it extends, the interfaces it implements, the name of the method that executes the expression, the exceptions that this method (i.e. the expression) is allowed to throw, and the ClassLoader that is used to define the generated class and to load classes referenced by the expression.
Alternatively, a number of "convenience constructors" exist that execute the steps described above instantly.
If you want to compile many expressions at the same time, you have the option to cook an array of expressions in one ExpressionEvaluator by using the following methods:
Notice that these methods have array parameters in contrast to their one-expression brethren.
Notice that for functionally identical ExpressionEvaluators,
java.lang.Object#equals(java.lang.Object) will return true
. E.g. "a+b" and
"c + d" are functionally identical if "a" and "c" have the same type, and so do "b" and "d".
If the parameter and return types of the expression are known at compile time, then a "fast"
expression evaluator can be instantiated through
(String, Class, String[], ClassLoader)
. Expression
evaluation is faster than through (Object[])
, because it is not done through
reflection but through direct method invocation.
Example:
public interface Foo { int bar(int a, int b); } ... Foo f = (Foo) ExpressionEvaluator.createFastExpressionEvaluator( "a + b", // expression to evaluate Foo.class, // interface that describes the expression's signature new String[] { "a", "b" }, // the parameters' names (ClassLoader) null // Use current thread's context class loader ); System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expressionNotice: The
interfaceToImplement
must either be declared public
,
or with package scope in the root package (i.e. "no" package).
On my system (Intel P4, 2 GHz, MS Windows XP, JDK 1.4.1), expression "x + 1" evaluates as follows:
Server JVM | Client JVM | |
---|---|---|
Normal EE | 23.7 ns | 64.0 ns |
Fast EE | 31.2 ns | 42.2 ns |
The expression may refer to a set of parameters with the given
parameterNames
and parameterTypes
.
parameterNames
and parameterTypes
must have the
same number of elements.
The parameters and/or the return value can be of primitive type, e.g. Double#TYPE.
The optionalClassLoader
serves two purposes:
optionalClassLoader
is null
, then the
current thread's context class loader is used.
A number of constructors exist that provide useful default values for the various parameters, or parse their script from a String instead of a Scanner. (You hardly want to use a scanner other than the default scanner.)
If the type of the expression is not fixed, you can pass a
If null
optionalExpressionType
argument; in this case, references are
returned as Objects, and primitive values are wrapped in their
wrapper classes.
optionalExpressionType
is Void#TYPE, then the
expression must be an invocation of a void
method.
Field Summary | |
---|---|
static Class | ANY_TYPE |
Constructor Summary | |
---|---|
ExpressionEvaluator(String expression, Class expressionType, String[] parameterNames, Class[] parameterTypes)
Equivalent to ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setExpressionType(expressionType); ee.setParameters(parameterNames, parameterTypes); ee.cook(expression); | |
ExpressionEvaluator(String expression, Class expressionType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader)
Equivalent to ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setExpressionType(expressionType); ee.setParameters(parameterNames, parameterTypes); ee.setThrownExceptions(thrownExceptions); ee.setParentClassLoader(optionalParentClassLoader); ee.cook(expression); | |
ExpressionEvaluator(String expression, Class expressionType, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, Class optionalExtendedType, Class[] implementedTypes, ClassLoader optionalParentClassLoader)
Equivalent to ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setExpressionType(expressionType); ee.setParameters(parameterNames, parameterTypes); ee.setThrownExceptions(thrownExceptions); ee.setExtendedType(optionalExtendedType); ee.setImplementedTypes(implementedTypes); ee.setParentClassLoader(optionalParentClassLoader); ee.cook(expression); | |
ExpressionEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class[] implementedTypes, boolean staticMethod, Class expressionType, String methodName, String[] parameterNames, Class[] parameterTypes, Class[] thrownExceptions, ClassLoader optionalParentClassLoader)
Equivalent to ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setClassName(className); ee.setExtendedType(optionalExtendedType); ee.setImplementedTypes(implementedTypes); ee.setStaticMethod(staticMethod); ee.setExpressionType(expressionType); ee.setMethodName(methodName); ee.setParameters(parameterNames, parameterTypes); ee.setThrownExceptions(thrownExceptions); ee.setParentClassLoader(optionalParentClassLoader); ee.cook(scanner); | |
ExpressionEvaluator() |
Method Summary | |
---|---|
static Object | createFastExpressionEvaluator(String expression, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader)
Creates a "fast expression evaluator" from the given java.lang.String
expression , generating a class with the ExpressionEvaluator that
extends Object.
|
static Object | createFastExpressionEvaluator(Scanner scanner, String className, Class optionalExtendedType, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader)
Creates a "fast expression evaluator" from the given Scanner with no default
imports.
|
static Object | createFastExpressionEvaluator(Scanner scanner, String[] optionalDefaultImports, String className, Class optionalExtendedType, Class interfaceToImplement, String[] parameterNames, ClassLoader optionalParentClassLoader)
Creates a "fast expression evaluator".
|
protected Class | getDefaultReturnType() |
static String[] | guessParameterNames(Scanner scanner)
Guess the names of the parameters used in the given expression. |
protected Java.Block | makeBlock(int idx, Scanner scanner) |
void | setExpressionType(Class expressionType)
Define the type of the expression. |
void | setExpressionTypes(Class[] expressionTypes) |
ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setExpressionType(expressionType); ee.setParameters(parameterNames, parameterTypes); ee.cook(expression);
See Also: ExpressionEvaluator setExpressionType (String[], Class[])
cook
ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setExpressionType(expressionType); ee.setParameters(parameterNames, parameterTypes); ee.setThrownExceptions(thrownExceptions); ee.setParentClassLoader(optionalParentClassLoader); ee.cook(expression);
See Also: ExpressionEvaluator setExpressionType (String[], Class[])
(Class[])
setParentClassLoader cook
ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setExpressionType(expressionType); ee.setParameters(parameterNames, parameterTypes); ee.setThrownExceptions(thrownExceptions); ee.setExtendedType(optionalExtendedType); ee.setImplementedTypes(implementedTypes); ee.setParentClassLoader(optionalParentClassLoader); ee.cook(expression);
See Also: ExpressionEvaluator setExpressionType (String[], Class[])
(Class[])
setExtendedType (Class[])
setParentClassLoader cook
ExpressionEvaluator ee = new ExpressionEvaluator(); ee.setClassName(className); ee.setExtendedType(optionalExtendedType); ee.setImplementedTypes(implementedTypes); ee.setStaticMethod(staticMethod); ee.setExpressionType(expressionType); ee.setMethodName(methodName); ee.setParameters(parameterNames, parameterTypes); ee.setThrownExceptions(thrownExceptions); ee.setParentClassLoader(optionalParentClassLoader); ee.cook(scanner);See Also: ExpressionEvaluator setClassName setExtendedType
(Class[])
ScriptEvaluator setExpressionType setMethodName(String[], Class[])
(Class[])
setParentClassLoader cook
expression
, generating a class with the ExpressionEvaluator that
extends Object.
See the class description for an explanation of the "fast expression evaluator" concept.
See Also: (Scanner, String[], String, Class, Class, String[], ClassLoader)
ExpressionEvaluator
See the class description for an explanation of the "fast expression evaluator" concept.
See Also: (Scanner, String[], String, Class, Class, String[], ClassLoader)
ExpressionEvaluator
See the class description for an explanation of the "fast expression evaluator" concept.
Notice: The interfaceToImplement
must either be declared public
,
or with package scope in the same package as className
.
Parameters: scanner Source of expression tokens optionalDefaultImports Default imports, e.g. { "java.util.Map", "java.io.*" }
className Name of generated class optionalExtendedType Class to extend interfaceToImplement Must declare exactly the one method that defines the expression's signature parameterNames The expression references the parameters through these names optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
Returns: an object that implements the given interface and extends the optionalExtendedType
See Also: ExpressionEvaluator
See Also: Scanner
Defaults to ANY_TYPE.