核心思想
Java 与 MATLAB 混合编程的核心思想是 “让 Java 调用 MATLAB 的功能,而不是让 Java 代码直接运行在 MATLAB 环境中”,MATLAB 作为一个计算引擎,负责执行复杂的数值计算和算法,而 Java 作为主应用程序,负责用户界面、业务逻辑、数据交互和系统管理。

主流混合编程方法
目前主要有以下四种主流方法,我将逐一介绍:
- 使用 MATLAB Compiler (MCC) 生成 Java 可执行文件/库
- 使用 MATLAB Production Server (推荐用于生产环境)
- 通过 MATLAB Engine API for Java (需要 MATLAB 安装)
- 通过文件或网络进行数据交换 (最简单,但耦合度低)
使用 MATLAB Compiler (MCC) 生成 Java 可执行文件/库
这是最传统、最常用的方法之一,它将你的 MATLAB 函数编译成一个独立的 Java 库(.jar 文件)或一个可执行文件,从而脱离 MATLAB 环境运行。
工作原理
- 你编写一个 MATLAB 函数(
myCalculator.m)。 - 使用 MATLAB 的
Compiler(mcc) 命令将该函数打包成一个 Java 组件(.jar文件)。 - 在 Java 项目中,像调用普通 Java 库一样调用这个
.jar文件。
优点
- 独立性:生成的
.jar文件不依赖 MATLAB 运行时环境,可以在任何安装了 JVM 的机器上运行。 - 封装性好:可以完美隐藏 MATLAB 代码的实现细节,只暴露必要的接口。
- 部署简单:只需要将生成的
.jar文件及其依赖库部署到 Java 应用服务器上即可。
缺点
- 支持有限:并非所有 MATLAB 功能都支持,特别是:
- 不支持图形用户界面。
- 不支持部分工具箱函数(如特定硬件交互、数据库工具箱等)。
- 不支持脚本文件(
.m文件),只能编译函数。 - 不支持
eval,feval,load,save等动态执行或文件 I/O 操作(除非使用特定的编译器指令)。
- 性能问题:首次调用时可能会有较慢的启动开销(JVM 加载和库初始化)。
- 数据类型转换:MATLAB 和 Java 之间的数据类型需要转换,可能会引入额外的性能开销。
适用场景
- 将核心算法作为服务或库,部署到没有 MATLAB 环境的生产服务器上。
- 需要将算法集成到 Java 桌面应用中,并希望用户无需安装 MATLAB。
操作步骤
编写 MATLAB 函数
创建一个 myCalculator.m 文件:
function result = myCalculator(a, b)
% 一个简单的计算函数
result = a^2 + b^2;
end
使用 MATLAB Compiler 进行编译 在 MATLAB 命令窗口中运行:

# 生成一个包含 Java 包装器的 JAR 文件 mcc -W java:myCalculator -T deploy:lib myCalculator.m
-W java:myCalculator: 指定生成 Java 包装器,组件名为myCalculator。-T deploy:lib: 指定生成库文件(.jar)。- 执行后,你会得到
myCalculator.jar和myCalculator.ctf(一个组件技术文件)。
在 Java 项目中调用
将生成的 myCalculator.jar 添加到你的 Java 项目的 Classpath 中。
import com.mathworks.toolbox.javabuilder.*;
import myCalculator.*;
public class JavaMatlabTest {
public static void main(String[] args) {
try {
// 1. 创建 MATLAB 组件实例
// myCalculator 是你在 mcc 命令中指定的名称
MWNumericArray a = new MWNumericArray(3.0, MWTypes.DOUBLE);
MWNumericArray b = new MWNumericArray(4.0, MWTypes.DOUBLE);
// 2. 调用 MATLAB 函数
// myCalculator 是 .m 文件名,calculate 是函数名
Object[] result = myCalculator.myCalculator(1, new Object[]{a, b});
// 3. 处理结果
// 结果被包装在 MWNumericArray 中
MWNumericArray resultArray = (MWNumericArray) result[0];
double output = resultArray.getDouble();
System.out.println("The result from MATLAB is: " + output); // 输出 25.0
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:你需要下载并安装 MATLAB Compiler Runtime (MCR),这是运行编译后代码的免费运行时环境,在部署时,必须将 MCR 与你的 Java 应用一起分发。
使用 MATLAB Production Server (MPS)
这是 MathWorks 官方推荐用于生产环境 的方法,它将 MATLAB 计算能力作为一个独立的服务运行。
工作原理
- 你将 MATLAB 函数部署到 MATLAB Production Server 上。
- Java 应用通过网络(通常是 REST API 或 gRPC)向 Server 发送计算请求(包含输入参数)。
- Server 执行计算,并将结果通过网络返回给 Java 应用。
优点
- 高性能:Server 专为高并发、低延迟的计算任务设计,性能远超 MCR 方案。
- 可扩展性:可以轻松部署多个 Server 实例,通过负载均衡器来应对高并发请求。
- 集中管理:所有 MATLAB 逻辑都集中在 Server 端,便于版本更新和维护。
- 语言无关:不仅限于 Java,任何能发送 HTTP 请求的语言(如 Python, C++, JavaScript)都可以调用。
- 支持更全面:比 Compiler 支持更多的 MATLAB 功能。
缺点
- 需要额外许可:MATLAB Production Server 是一个需要单独购买的商业产品。
- 架构复杂:引入了一个新的服务组件,增加了系统的复杂性和部署成本。
适用场景
- 企业级应用,需要处理大量并发请求。
- 微服务架构,将算法能力作为一个独立的服务提供。
- 需要高可用和高性能的计算后端。
操作步骤
- 安装和配置 MATLAB Production Server。
- 创建并打包 MATLAB 函数(通常使用
deploytool创建一个.jar或.zip部署包)。 - 将部署包部署到 Server 上。
- 在 Java 中调用:
- 使用 HTTP 客户端(如 Apache HttpClient, OkHttp, Spring
RestTemplate)发送 POST 请求。 - 请求数据通常是 JSON 格式。
- 使用 HTTP 客户端(如 Apache HttpClient, OkHttp, Spring
Java 调用示例 (使用 OkHttp)
import okhttp3.*;
public class MpsClient {
private static final String MPS_URL = "http://your-matlab-production-server:9910/myCalculator/calculate";
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
// 1. 构造请求体 (JSON格式)
String jsonBody = "{\"a\": 3.0, \"b\": 4.0}";
RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
// 2. 创建请求
Request request = new Request.Builder()
.url(MPS_URL)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
// 3. 获取并处理响应
String responseBody = response.body().string();
System.out.println("Response from MPS: " + responseBody);
// 解析 JSON 响应,提取结果...
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用 MATLAB Engine API for Java
如果你只是想在本地开发环境中让 Java 直接调用 MATLAB,并且开发机器上已经安装了 MATLAB,那么这是最直接、最简单的方法。
工作原理
Java 通过一个本地库(javabuilder.jar 和对应的本地 .dll 或 .so 文件)直接启动和控制一个 MATLAB 进程。
优点
- 功能最全:可以调用 MATLAB 的所有功能,包括脚本、图形界面、工具箱等。
- 开发简单:API 直观,数据传递方便,无需复杂的编译和打包步骤。
- 性能好:进程内通信,没有网络延迟。
缺点
- 依赖 MATLAB 环境:运行 Java 程序的机器上必须安装 MATLAB。
- 不能用于生产部署:MATLAB 是一个昂贵的商业软件,不可能在每个服务器或客户端上都安装一份。
- 启动慢:每次调用都需要启动一个完整的 MATLAB 进程。
适用场景
- 原型开发和测试:快速验证算法集成方案。
- 桌面应用:开发一个需要 MATLAB 强大计算能力的桌面软件,并且用户可以接受安装 MATLAB。
- 数据分析和脚本:用 Java 编写 GUI,用 MATLAB 执行后台计算。
操作步骤
- 确保 MATLAB 已安装。
- 配置 Java 项目:
- 将 MATLAB 安装路径下的
extern/engines/java/jar目录下的javabuilder.jar添加到项目的 Classpath。 - 将
extern/bin/win64(Windows) 或extern/bin/glnxa64(Linux) 或extern/bin/maci64(macOS) 目录添加到 JVM 的java.library.path中。
- 将 MATLAB 安装路径下的
- 编写 Java 代码
import com.mathworks.engine.*;
import java.util.concurrent.*;
public class MatlabEngineExample {
public static void main(String[] args) {
try {
// 1. 启动 MATLAB Engine,会阻塞直到 MATLAB 启动
MatlabEngine eng = MatlabEngine.startMatlab();
// 2. 将数据发送到 MATLAB 工作区
eng.putVariable("x", 10);
// 3. 执行 MATLAB 命令
eng.eval("y = x^2 + 2*x + 1;");
// 4. 从 MATLAB 工作区获取数据
double y = eng.getVariable("y");
System.out.println("The result from MATLAB is: " + y); // 输出 121.0
// 5. 关闭 MATLAB Engine
eng.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过文件或网络进行数据交换
这是一种最“原始”的耦合方式,但非常灵活。
工作原理
Java 程序将输入数据写入一个文件(如 CSV, .mat, .txt),然后通过命令行调用 MATLAB 脚本(.m 文件)或可执行文件,MATLAB 脚本读取文件,进行计算,并将结果写入另一个文件,Java 程序再读取结果文件。
优点
- 完全解耦:Java 和 MATLAB 是两个独立的进程,互不依赖。
- 简单直观:无需任何特殊的工具或库,只需要文件读写和进程调用。
- 支持所有功能:因为 MATLAB 是在完整环境下运行的。
缺点
- 性能极差:涉及大量的磁盘 I/O 操作,速度非常慢。
- 难以管理:文件命名、路径管理、并发访问等问题会很复杂。
- 实时性差:不适合需要快速响应的场景。
适用场景
- 批处理任务,对性能要求不高。
- 系统集成非常困难,且没有其他选择时。
- 简单的、一次性的数据转换任务。
总结与选择建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| MATLAB Compiler | 独立部署,封装性好 | 支持功能有限,有 MCR 依赖 | 将算法集成到无 MATLAB 环境的生产环境或桌面应用 |
| MATLAB Production Server | 高性能,高并发,可扩展 | 需要额外许可,架构复杂 | 企业级生产环境,微服务架构 |
| MATLAB Engine API | 功能最全,开发简单 | 依赖 MATLAB 安装,不能用于生产 | 原型开发,桌面应用,测试 |
| 文件/网络交换 | 完全解耦,简单 | 性能极差,管理复杂 | 批处理,系统集成困难时的备选方案 |
如何选择?
- 如果你正在做原型开发或测试:直接使用 MATLAB Engine API,最快最方便。
- 如果你的目标是开发一个桌面应用,并且用户愿意安装 MATLAB:MATLAB Engine API 仍然是首选。
- 如果你的目标是企业级生产环境,特别是 Web 服务或高并发应用:强烈推荐使用 MATLAB Production Server,这是最稳定、最可扩展的方案。
- 如果你的项目预算有限,且计算量不大,只需要将算法打包成一个库:可以使用 MATLAB Compiler 生成
.jar文件,并免费分发 MCR。 - 如果以上方法都不可行:才考虑文件交换这种最后的手段。
