Marko's comment on the question is correct. You can't read a bare Java lambda expression out of a file, since such an expression isn't defined without a target type provided by the context. For example, consider the following method declarations:
void method1(BiFunction<String,String,String> f) { ... }
void method2(BiFunction<Integer,Integer,Integer> f) { ... }
Then in the following code,
method1((x, y) -> x + y);
method2((x, y) -> x + y);
the two lambda expressions (x, y) -> x + y
mean completely different things. For method1, the +
operator is string concatenation, but for method2, it means integer addition.
This is wandering a bit far afield from your question, but you can read and evaluate a lambda or function expression using a dynamic language. In Java 8 there is the Nashorn JavaScript engine. So instead of attempting to read an evaluate a Java lambda expression, you could read and evaluate a JavaScript function using Nashorn, called from Java.
The following code takes a function in arg[0] and applies it to each subsequent, printing the results:
import java.util.function.Function;
import javax.script.*;
public class ScriptFunction {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
@SuppressWarnings("unchecked")
Function<Object,Object> f = (Function<Object,Object>)engine.eval(
String.format("new java.util.function.Function(%s)", args[0]));
for (int i = 1; i < args.length; i++) {
System.out.println(f.apply(args[i]));
}
}
}
For example, running the command
java ScriptFunction 'function(x) 3 * x + 1' 17 23 47
gives the results
52.0
70.0
142.0
The wrapping of the function string inside of new java.util.function.Function
is necessary in order to create an adapter between Nashorn's notion of a JavaScript function and Java's Function interface. (There might be a better way, but I'm not aware of one.) The cast of the return value of eval
to Function<Object,Object>
results in an unchecked cast warning, which is unavoidable, I think, since this is the boundary between JavaScript, a dynamically-typed language, and Java, which is statically-typed. Finally, no error checking is done. I'm sure this will blow up in a variety of nasty ways if certain assumptions are violated, such as the first argument not actually representing a JavaScript function.
Still, you might find this technique useful if you have a need to evaluate expressions or functions read from a file.