我们来做一个核心区分:

| 特性 | Java | JavaScript |
|---|---|---|
| 类型系统 | 强类型、静态类型 | 弱类型、动态类型 |
| 运行环境 | JVM (Java虚拟机) | 浏览器、Node.js |
| 编译/解释 | 编译为字节码,由JVM解释执行 | 解释执行 (或JIT编译) |
| 主要用途 | 企业级后端应用、安卓App、大数据处理 | 网页前端、服务器端、桌面应用 |
| 关系 | 无直接关系,只是名字相似 | 最初是为了让Java在浏览器中运行而设计,后独立发展 |
我们来看如何在 Java 的世界里使用 JavaScript。
在服务器端执行 JavaScript 代码 (最常见)
这是最经典和最实用的场景,你可以在一个 Java 后端服务(如 Spring Boot)中嵌入一个 JavaScript 引擎,用来处理一些逻辑,
- 配置文件解析:使用 JSON 或 JavaScript 对象来配置复杂的业务规则。
- 规则引擎:将业务规则用 JavaScript 编写,存储在数据库或文件中,运行时动态加载和执行,实现业务逻辑与代码的分离。
- 脚本化功能:为你的应用提供一个脚本接口,允许用户或开发者编写脚本来扩展功能。
- 测试:用 JavaScript 编写测试用例来测试 Java 代码。
在 Java 中,执行 JavaScript 代码最标准、最现代的方式是使用 Nashorn 和 GraalVM。
使用 Nashorn (Java 8+ 内置)
Nashorn 是 Java 8 引入的 JavaScript 引擎,它允许在 JVM 上直接运行 JavaScript 代码,虽然从 Java 11 开始 Nashorn 已被标记为“废弃”,但在 Java 8 环境中它仍然是一个非常可靠的选择。

示例代码:
import javax.script.*;
public class NashornExample {
public static void main(String[] args) throws ScriptException {
// 1. 获取 ScriptEngineManager
ScriptEngineManager manager = new ScriptEngineManager();
// 2. 获取 Nashorn 引擎 (通过名称 "nashorn" 或 "javascript")
ScriptEngine engine = manager.getEngineByName("nashorn");
if (engine == null) {
System.out.println("Nashorn engine not found!");
return;
}
System.out.println("--- Nashorn Example ---");
// 3. 执行简单的 JavaScript 表达式
engine.eval("var name = 'World';");
engine.eval("print('Hello, ' + name);"); // 使用 print 函数
// 4. 从 Java 向 JavaScript 传递变量
engine.put("user", "Alice");
engine.eval("print('Welcome, ' + user);");
// 5. 从 JavaScript 调用 Java 方法
engine.eval("var list = new java.util.ArrayList();");
engine.eval("list.add('Item 1');");
engine.eval("list.add('Item 2');");
@SuppressWarnings("unchecked")
java.util.ArrayList<String> resultList = (java.util.ArrayList<String>) engine.get("list");
System.out.println("List from JavaScript: " + resultList);
// 6. 调用 Java 的静态方法
engine.eval("var System = Java.type('java.lang.System'); System.out.println('Current time: ' + System.currentTimeMillis());");
}
}
如何运行: 确保你使用的是 Java 8 或更高版本(但低于 Java 11),直接编译并运行即可。
使用 GraalVM (现代推荐)
GraalVM 是一个高性能的 JDK,它包含了一个名为 Graal.js 的新一代 JavaScript 引擎,它比 Nashorn 更快,支持更新的 ECMAScript 标准,并且与 Java 生态集成得更好,这是目前强烈推荐的方式。
步骤:

- 下载并使用 GraalVM:首先你需要下载 GraalVM JDK 并设置环境变量。
- 添加 Maven 依赖:在你的 Maven 项目中添加
js和js-scriptengine依赖。
<dependencies>
<!-- GraalVM JavaScript Engine -->
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>23.1.0</version> <!-- 请使用最新的版本 -->
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>23.1.0</version>
</dependency>
</dependencies>
示例代码:
GraalVM 的 API 与 Nashorn 兼容,所以上面的代码几乎可以原封不动地运行,只需要将 getEngineByName("nashorn") 改为 getEngineByName("graal.js")。
// ... (ScriptEngineManager manager = new ScriptEngineManager();)
ScriptEngine engine = manager.getEngineByName("graal.js"); // 关键改动
// ... (其余代码与 Nashorn 示例完全相同)
GraalVM 的优势:
- 性能卓越:使用 GraalVM 的即时编译器,性能远超 Nashorn。
- ES6+ 支持:支持现代 JavaScript 语法。
- Node.js 兼容性:可以运行部分 Node.js 应用。
- 多语言:同一个 JVM 上可以无缝切换 JavaScript、Python、Ruby 等语言。
在浏览器中运行 (前端)
这是 JavaScript 的主战场,你不会在浏览器中直接“运行 Java 代码”,而是通过以下方式让 Java 和 JavaScript 交互:
Java Applet (已废弃)
这是最早的方式,允许在网页中嵌入一个由 Java 编写的小程序,但由于安全、性能和兼容性问题,Applet 已经被所有现代浏览器弃用。现在不应再使用此技术。
GWT (Google Web Toolkit)
GWT 是一个前端框架,允许你用 Java 语言编写前端代码,GWT 编译器会将其翻译成优化的 JavaScript 代码,在浏览器中运行,它主要用于构建复杂的企业级 Web 应用的前端。
特点:
- 用 Java 编写前端:对 Java 开发者非常友好。
- 类型安全:利用 Java 的强类型系统来减少前端错误。
- RPC 支持:可以像调用本地 Java 方法一样调用后端服务。
通过 HTTP API 交互 (最现代、最灵活的方式)
这是目前最主流和推荐的方式,Java 后端(用 Spring Boot、Jakarta EE 或 Micronaut 框架构建)提供一个 RESTful API,JavaScript (在浏览器或 Node.js 中) 通过 fetch 或 axios 等 HTTP 客户端来调用这个 API。
工作流程:
- Java 后端:提供一个 HTTP 端点,
POST /api/calculate。 - JavaScript 前端:捕获用户输入,然后发送一个 HTTP 请求到该端点,通常以 JSON 格式发送数据。
- Java 后端:接收请求,处理业务逻辑(可能涉及数据库操作等),然后将结果以 JSON 格式返回。
- JavaScript 前端:接收 JSON 响应,并更新网页的 DOM(文档对象模型)来展示结果。
示例:
-
Java (Spring Boot) 后端控制器
@RestController @RequestMapping("/api") public class HelloController { @PostMapping("/greet") public Map<String, String> greetUser(@RequestBody Map<String, String> payload) { String name = payload.get("name"); Map<String, String> response = new HashMap<>(); response.put("message", "Hello from Java, " + name + "!"); return response; } } -
JavaScript (浏览器) 前端
async function callJavaApi() { const name = document.getElementById('nameInput').value; const response = await fetch('/api/greet', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: name }), }); if (!response.ok) { throw new Error('Network response was not ok'); } const data = await response.json(); document.getElementById('result').innerText = data.message; }
在桌面应用中执行
如果你正在开发一个 Java 桌面应用(例如使用 JavaFX 或 Swing),你也可以在应用中嵌入 JavaScript 引擎(如 Nashorn 或 GraalVM)来增加动态脚本功能。
示例 (JavaFX + Nashorn): 你可以创建一个文本区域让用户输入 JavaScript 代码,然后点击按钮执行,并在另一个区域显示结果。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.script.*;
public class JSScriptRunner extends Application {
private ScriptEngine engine;
private TextArea outputArea;
@Override
public void start(Stage primaryStage) {
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName("nashorn");
outputArea = new TextArea();
outputArea.setEditable(false);
TextArea codeArea = new TextArea("print('Hello from Nashorn in JavaFX!');\n2 + 2;");
Button runButton = new Button("Run Script");
runButton.setOnAction(e -> {
try {
outputArea.setText(engine.eval(codeArea.getText()).toString());
} catch (ScriptException ex) {
outputArea.setText("Error: " + ex.getMessage());
}
});
VBox root = new VBox(10, new Label("JavaScript Code:"), codeArea, runButton, new Label("Output:"), outputArea);
Scene scene = new Scene(root, 500, 400);
primaryStage.setTitle("JS Runner in JavaFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
总结与建议
| 场景 | 推荐技术 | 说明 |
|---|---|---|
| 服务器端执行 JS | GraalVM | 现代、高性能,是 Nashorn 的继任者,如果你使用 Java 8,Nashorn 也可以。 |
| 浏览器端交互 | HTTP API (REST/GraphQL) | 最灵活、最标准的方式,前后端完全解耦。 |
| 桌面应用脚本化 | GraalVM / Nashorn | 在 JavaFX/Swing 应用中提供动态脚本能力。 |
| 前端开发 | GWT (特定场景) | 如果团队是纯 Java 开发者且希望保持一致性,可以考虑。 |
- 想在 Java 程序里运行 JS 代码,用 GraalVM。
- 想让网页上的 JS 和 Java 后端通信,用 HTTP API。
- 不要再尝试使用 Applet 或其他过时的技术。
