导读:本期聚焦于小伙伴创作的《在Java中如何利用JavaScript引擎解析并计算数学表达式字符串》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《在Java中如何利用JavaScript引擎解析并计算数学表达式字符串》有用,将其分享出去将是对创作者最好的鼓励。

在Java开发中,动态解析并计算数学表达式字符串是一个常见需求,比如处理用户自定义的计算公式、动态配置的业务规则等场景。手动实现表达式词法分析、语法解析和计算过程逻辑复杂,容易引入错误,而Java内置的JavaScript引擎可以直接执行符合JavaScript语法的数学表达式,大幅降低实现成本。

在Java中如何利用JavaScript引擎解析并计算数学表达式字符串

Java中可用的JavaScript引擎

Java从JDK 1.6开始就内置了JavaScript引擎支持,不同JDK版本对应的引擎有所区别:

  • JDK 1.6到JDK 1.7:默认使用Rhino引擎,由Mozilla提供
  • JDK 1.8:默认使用Nashorn引擎,是Oracle推出的新一代JavaScript引擎,性能优于Rhino
  • JDK 9及之后版本:Nashorn引擎被标记为废弃,JDK 15之后正式移除,需要手动引入第三方引擎如GraalVM JavaScript引擎

基于ScriptEngineManager实现表达式计算

Java提供了javax.script包来支持脚本引擎的调用,核心类包括ScriptEngineManagerScriptEngine,我们可以通过这些类获取JavaScript引擎并执行表达式。

基础计算实现

以下是一个简单的示例,演示如何计算基本的数学表达式:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class MathExpressionCalculator {
    public static void main(String[] args) {
        // 创建脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();
        // 获取JavaScript引擎,参数传入"JavaScript"或者"nashorn"等引擎名称
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        
        // 待计算的数学表达式字符串
        String expression = "3 + 5 * (2 - 4) / 2";
        
        try {
            // 执行表达式并获取结果
            Object result = engine.eval(expression);
            System.out.println("表达式 " + expression + " 的计算结果为:" + result);
        } catch (ScriptException e) {
            System.out.println("表达式计算失败,错误信息:" + e.getMessage());
        }
    }
}

上述代码中,首先通过ScriptEngineManager获取JavaScript引擎,然后调用eval方法执行表达式字符串,执行成功后会返回计算结果,如果表达式语法错误则会抛出ScriptException

支持变量和复杂表达式

JavaScript引擎还支持在表达式中引入变量,我们可以先定义变量再执行包含变量的表达式:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.HashMap;
import java.util.Map;

public class VariableExpressionCalculator {
    public static void main(String[] args) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        
        // 定义变量和对应的值
        Map<String, Object> variables = new HashMap<>();
        variables.put("a", 10);
        variables.put("b", 20);
        variables.put("c", 5);
        
        // 包含变量的表达式
        String expression = "a * b + c / 2";
        
        try {
            // 先向引擎中注入变量
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                engine.put(entry.getKey(), entry.getValue());
            }
            // 执行表达式
            Object result = engine.eval(expression);
            System.out.println("带变量的表达式计算结果:" + result);
        } catch (ScriptException e) {
            System.out.println("计算失败:" + e.getMessage());
        }
    }
}

不同JDK版本的适配方案

由于JDK版本不同内置的JavaScript引擎有差异,我们需要根据实际使用的JDK版本选择合适的实现方案:

JDK版本可用引擎实现方式
JDK 1.6 - JDK 1.7Rhino直接使用ScriptEngineManager获取"JavaScript"引擎即可
JDK 1.8Nashorn可以获取"JavaScript"或者"nashorn"引擎,性能更优
JDK 9及以上(Nashorn已移除)GraalVM JavaScript需要手动引入GraalVM JavaScript依赖,再通过ScriptEngineManager获取引擎

JDK 15+引入GraalVM引擎示例

如果使用的是JDK 15及以上版本,需要先在项目中引入GraalVM JavaScript的依赖,以Maven项目为例,添加以下依赖:

<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js</artifactId>
    <version>22.3.0</version>
</dependency>
<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js-scriptengine</artifactId>
    <version>22.3.0</version>
</dependency>

引入依赖后,代码实现和之前的逻辑基本一致,引擎管理器会自动识别到GraalVM的JavaScript引擎:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class GraalVMCalculator {
    public static void main(String[] args) {
        ScriptEngineManager manager = new ScriptEngineManager();
        // 获取GraalVM JavaScript引擎
        ScriptEngine engine = manager.getEngineByName("graal.js");
        
        String expression = "Math.pow(2, 10) + 100";
        try {
            Object result = engine.eval(expression);
            System.out.println("计算结果:" + result);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
}

使用注意事项

表达式安全性问题

如果表达式字符串来自用户输入,直接执行会存在安全风险,比如用户输入java.lang.System.exit(0)这样的恶意代码,会导致程序异常退出。因此需要对用户输入的表达式做严格的校验,只允许包含数字、四则运算符号、括号、数学函数等合法内容,过滤掉所有脚本相关的关键字和调用。

异常处理

执行表达式时可能会抛出多种异常,除了ScriptException之外,还可能遇到NullPointerException等问题,建议对执行过程做完整的异常捕获,同时给表达式执行设置超时时间,避免恶意输入导致线程阻塞。

数据类型转换

引擎执行表达式返回的结果类型是Object,实际可能是IntegerDouble等类型,需要根据业务需求做对应的类型转换,避免类型转换错误。

总结

借助Java的JavaScript引擎可以低成本的实现数学表达式字符串的解析和计算,无需手动编写复杂的解析逻辑。开发者需要根据自己的JDK版本选择合适的引擎,同时注意表达式的安全性校验和异常处理,确保功能稳定可靠。如果需要更高性能或者更复杂的表达式支持,也可以考虑结合其他专门的表达式解析库使用。

JavaJavaScript_engineNashorn数学表达式解析字符串计算修改时间:2026-06-17 01:06:42

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。