Marko对这个问题的评论是正确的。你不能从文件中读取一个空的Java lambda表达式,因为这样的表达式没有定义没有上下文提供的目标类型。例如,考虑以下方法声明:
void method1(BiFunction f) { ... }
void method2(BiFunction f) { ... }
然后在下面的代码中,
method1((x, y) -> x + y);
method2((x, y) -> x + y);
两个lambda表达式(x,y) x y意味着完全不同的东西。对于method1,运算符是字符串连接,但对于method2,它表示整数加法。
这是远离你的问题,但你可以读取和评估lambda或函数表达式使用动态语言。在Java 8中有Nashorn JavaScript引擎。因此,不是尝试读取一个评估一个Java lambda表达式,你可以读取和评估一个JavaScript函数使用Nashorn,从Java调用。
以下代码在arg [0]中使用一个函数,并将其应用于每个后续的打印结果:
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 f = (Function)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]));
}
}
}
例如,运行命令
java ScriptFunction 'function(x) 3 * x + 1' 17 23 47
给出结果
52.0
70.0
142.0
为了在Nashorn的JavaScript函数概念和Java的Function接口之间创建一个适配器,需要在新的java.util.function.Function中包装函数字符串。 (可能有更好的方法,但我不知道一个。)eval的返回值的转换为Function< Object,Object>导致一个未检查的强制转换警告,这是不可避免的,我认为,因为这是JavaScript,动态类型语言和Java之间的边界,静态类型。最后,不进行错误检查。我相信如果违反某些假设,如果第一个参数实际上不代表一个JavaScript函数,这将以各种各样的讨厌的方式爆炸。
但是,如果需要评估从文件读取的表达式或函数,您可能会发现此方法很有用。