Вычисление строковых математических выражений в Java
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
В языке Java вы можете выполнить код на JavaScript с помощью класса javax.script.ScriptEngineManager
. Вот пример использования:
import javax.script.*;
public class QuickEval {
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
System.out.println(engine.eval("10 * 2 + 1")); // Результат: 21
}
}
Важное замечание: Выполнение кода на JavaScript в Java не предполагает непосредственной интерпретации Java-кода. Для этого вам потребуется использовать Java Compiler API или сторонние библиотеки, такие как Janino или BeanShell.
Подробное руководство по функционалу, сходному с eval(), в Java
Давайте подробно рассмотрим динамическое выполнение кода, возможные альтернативы и риски, связанные с применением функционала, аналогичного eval()
в Java.
Риски безопасности при использовании аналога eval()
Использование eval()
может подвергнуть ваш код атакам с инъекцией кода. По этой причине применение ScriptEngine
для выполнения кода на JavaScript считается относительно безопасным. Однако к непроверенным данным следует относиться с осторожностью. При использовании Java Compiler API растёт риск выполнения небезопасного кода.
Создание безопасных парсеров выражений
Как безопасную альтернативу можно рассмотреть создание собственного парсера, такого как рекурсивный спуск или конечные автоматы. Для обработки сложных выражений полезным может оказаться ANTLR, хотя это потребует дополнительного времени на освоение.
Использование сторонних библиотек
Для выполнения более сложных задач можно воспользоваться сторонними библиотеками, такими как Exp4j для математических вычислений или JEL (Java Expression Language) для работы с кодом на более высоком уровне.
Период после Nashorn
После окончания поддержки Nashorn стоит поискать альтернативы для встраивания JavaScript или присмотреться к языкам, поддерживающим API для скриптов, таким как Groovy.
JShell (Java 9 и выше)
С появлением Java 9 был введён JShell, который позволяет интерпретировать Java-выражения в режиме REPL. Однако JShell больше подходит для разработки в интерактивном режиме, чем для продакшен-использования.
Паттерны проектирования как альтернатива
Если вам требуется изменять код во время выполнения, вместо функционала типа eval()
можно применить паттерны проектирования, такие как Стратегия, Команда или Строитель.
Пример разработки настольного калькулятора
В качестве примера из реальной жизни можно рассмотреть настольный калькулятор. Для интерпретации выражений можно реализовать алгоритм обратной польской записи.
Визуализация
Java без встроенного аналога eval()
можно сравнить с набором инструментов, в котором отсутствует один из них:
Набор инструментов Java 🧰: [Молоток 🔨, Плоскогубцы 🛠, Гаечный ключ 🔧, Рулетка 📏]
Отсутствующий инструмент: Отвертка Eval 🪛 (не найдена!)
Для того чтобы активировать функционал, аналогичный eval()
, в Java, вы можете "создать" свой инструмент:
Самодельная отвертка 🪛:
1. ScriptEngineManager 🧙♂️
2. JavaScript-движок 📜
3. Выполнение кода, схожее с Eval 🎭
Важно помнить: К динамическому выполнению кода следует относиться с такой же осторожностью, как к использованию самодельного инструмента.
Компиляция исходного кода Java в байт-код
Можно выполнить Java-код, динамически созданный в реальном времени, путем компилирования исходного кода в байт-код. При этом не забывайте о необходимости глубокого понимания работы загрузчиков классов и безопасности виртуальной машины Java.
Использование удобных библиотек для оценки выражений
Учитывая большой выбор сторонних библиотек, вы можете рассмотреть MVEL, JEval или другие специализированные библиотеки, о которых упоминали пользователи на Stack Overflow.
Полезные материалы
- ScriptEngine (Java Platform SE 8) — официальная документация Java по выполнению JavaScript-кода.
- Существует ли в Java функция eval()? – Stack Overflow — обсуждение различных альтернатив функции eval() в Java среди членов сообщества Stack Overflow.
- BeanShell – Lightweight Scripting for Java — обзор BeanShell, скриптовой оболочки для Java.
- JavaCompiler (Java Platform SE 8) — документация по API JavaCompiler для выполнения Java-кода на лету.
- Janino by janino-compiler — описание Janino, встроенного компилятора Java.
- The Apache Groovy Programming Language — руководство по Apache Groovy, скриптовому языку, тесно связанному с Java.
- Руководство пользователя JShell (Java SE) — инструкция по работе с JShell, интерактивным инструментом REPL в Java 9.