马尔科对这个问题的评论是正确的。您无法从文件中读取裸 Java lambda 表达式,因为如果没有上下文提供的目标类型,则不会定义此类表达式。例如,请考虑以下方法声明:
void method1(BiFunction<String,String,String> f) { ... }
void method2(BiFunction<Integer,Integer,Integer> f) { ... }
然后在下面的代码中,
method1((x, y) -> x + y);
method2((x, y) -> x + y);
这两个 lambda 表达式的含义完全不同。对于方法 1,运算符是字符串串联,但对于方法 2,它表示整数加法。(x, y) -> x + y
+
这离你的问题有点远,但你可以使用动态语言阅读和计算 lambda 或函数表达式。在Java 8中有Nashorn JavaScript引擎。因此,与其尝试读取计算 Java lambda 表达式,不如使用从 Java 调用的 Nashorn 读取和计算 JavaScript 函数。
下面的代码在 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<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]));
}
}
}
例如,运行命令
java ScriptFunction 'function(x) 3 * x + 1' 17 23 47
给出结果
52.0
70.0
142.0
为了在 Nashorn 的 JavaScript 函数概念和 Java 的函数接口之间创建一个适配器,必须将函数字符串包装在 里面。(可能有更好的方法,但我不知道有。返回值 to 的强制转换会导致未经检查的强制转换警告,我认为这是不可避免的,因为这是 JavaScript(一种动态类型语言)和 Java(静态类型化语言)之间的边界。最后,不执行错误检查。我敢肯定,如果违反了某些假设,这将以各种令人讨厌的方式爆炸,例如第一个参数实际上并不代表JavaScript函数。new java.util.function.Function
eval
Function<Object,Object>
不过,如果您需要计算从文件中读取的表达式或函数,则可能会发现此技术很有用。