Ответ 1
Марко прокомментировал вопрос правильно. Вы не можете прочитать явное выражение lambda Java из файла, поскольку такое выражение не определено без целевого типа, предоставляемого контекстом. Например, рассмотрите следующие объявления методов:
void method1(BiFunction<String,String,String> f) { ... }
void method2(BiFunction<Integer,Integer,Integer> f) { ... }
Затем в следующем коде
method1((x, y) -> x + y);
method2((x, y) -> x + y);
два лямбда-выражения (x, y) -> x + y
означают совершенно разные вещи. Для метода1 оператор +
представляет собой конкатенацию строк, но для метода2 это означает добавление целых чисел.
Это блуждает немного далеко от вашего вопроса, но вы можете читать и оценивать выражение лямбда или функции с использованием динамического языка. В Java 8 есть JavaScript-движок Nashorn. Поэтому вместо того, чтобы пытаться прочитать выражение 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<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
Обертка строки функции внутри new java.util.function.Function
необходима для создания адаптера между понятием Nashorn функции JavaScript и интерфейсом Java Function. (Может быть, лучший способ, но я не знаю об этом.) Приведение возвращаемого значения от eval
до Function<Object,Object>
приводит к неконтролируемому предупреждению о бросании, которое, как мне кажется, неизбежно, поскольку это границы между JavaScript, динамически типизированным языком и Java, который статически типизирован. Наконец, проверка ошибок не выполняется. Я уверен, что это взорвется множеством неприятных способов, если некоторые допущения будут нарушены, например, первый аргумент, фактически не представляющий функцию JavaScript.
Тем не менее, вы можете найти этот метод полезным, если вам нужно оценить выражения или функции, считанные из файла.