大家好,小编来为大家解答以下问题,java和python能联合开发吗,java和python混合架构,今天让我们一起来看看吧!
文章目录
Java调用Python协同开发的方式
背景
Java与Python结合开发是指将Python语言与Java语言结合起来,利用它们的优势,共同开发一个应用程序。
Python语言拥有许多强大的特性,如易于学习、快速开发、可扩展性等,而Java语言则拥有跨平台、可靠性、安全性等优势,因此将它们结合起来,可以发挥出更大的作用python打印皮卡丘怎么弄。
在一个大型企业系统中,Java可能用于后端服务和业务逻辑,而Python可能用于数据分析和机器学习任务。在这种情况下,两种语言需要能够协同工作,以实现全面的功能。
环境准备
操作系统:Win11
Java开发环境:安装并配置了Java开发环境,包括Java Development Kit (JDK) 和设置了正确的环境变量。(这里就不详细讲JDK的安装了,可以参考 最详细jdk安装以及配置环境(保姆级教程))
Python解释器:安装Python解释器,并且可以在命令行中执行python命令。可以通过在命令行中输入python --version来验证Python是否正确安装。
下面开始下载安装Python、配置环境变量。
下载、安装Python解释器
下载Python
- 下载地址
Download Python | Python.org - 选择Windows版本,我这里下载的最新的
(最好选择Python3.x,因为Python2.x官方已经不再维护了)
安装Python
- 点击Python解释器(python-3.12.1-amd64.exe)运行
- 勾选[Add python.exe to PATH],添加到Python到环境变量中,我这里选择的Customize installation自定义安装。
- 直接点击【next】下一步。
- 选择为所有用户安装,配置自定义安装路径,这里我安装在D盘,点击Install
- 安装完成
- 检查Python解释器环境变量是否配置成功
右键[此电脑] -> 点击[属性] -> 进入[高级系统设置] -> 选择[环境变量]
- 查看系统变量Path(如果安装的时候没有选择添加到环境变量,则可以自行添加到此处)
- cmd运行,检查版本号
python --version
调用方法
系统需要有Python解释器环境。
一、使用命令行调用(较原始)
1.使用ProcessBuilder类调用Python
Java提供了ProcessBuilder类,可以在Java代码中调用外部程序或脚本。我们可以利用这个类调用Python解释器,从而执行Python的代码。通过使用ProcessBuilder类,我们可以传递命令行参数,获取脚本的输出结果,并实现Java与Python的互操作性。
- Java内执行命令代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PythonTest {
public static void main(String[] args) {
try {
// 创建ProcessBuilder对象,指定要执行的命令和参数
ProcessBuilder pb = new ProcessBuilder("python", "-c", "print('Hello, Python!')");
// 启动子进程并等待其完成
Process process = pb.start();
// 读取子进程的输出结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待子进程完成并获取退出值
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
2.使用Runtime.getRuntime().exec()调用
- 准备Python的测试文件 test.py
def say_hello(name):
return 'Hello, ' + name + '!'
if __name__ == '__main__':
print(say_hello('Python'))
- Java调用
public static void main(String[] args) {
try {
// 创建ProcessBuilder对象,指定要执行的命令和参数
ProcessBuilder pb = new ProcessBuilder("python", getResourceFilePath("test.py"));
// 启动子进程并等待其完成
Process process = pb.start();
// 读取子进程的输出结果
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 等待子进程完成并获取退出值
int exitCode = process.waitFor();
System.out.println("Exit Code: " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
/**
* 获取资源文件路径
* * @param fileName 文件名称
* @return 文件绝对路径
*/
public static String getResourceFilePath(String fileName) {
// 获取当前项目的根目录路径
String rootPath = System.getProperty("user.dir");
// 拼接资源文件夹的相对路径
String resourceFolderPath = rootPath + File.separator + "src" + File.separator + "test" + File.separator + "resources" + File.separator + fileName;
// 创建File对象,并打印资源文件夹的绝对路径
File resourceFolder = new File(resourceFolderPath);
// 打印资源文件夹的绝对路径
return resourceFolder.getAbsolutePath();
}
二、使用Jython(推荐)
Jython 是一个将Python代码嵌入到Java中的工具,它使Java应用程序能够调用和执行Python代码。这为Java开发人员提供了在其应用程序中集成Python脚本的能力。
在maven坐标中添加:
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.2</version>
</dependency>
编写Java代码测试:
public static void main(String[] args) {
PythonInterpreter interpreter = new PythonInterpreter();
interpreter.exec("print('Hello from Python!')");
}
运行结果:
三、使用JNI(Java Native Interface)(难度较高,笔者没有试过)
这个涉及到C语言编码,使用JNI调用Python C API来执行Python代码。通过C去调用python,再在Java中调用native方法去执行,需要将C语言编写的代码编译成动态链接库,并在Java代码中加载它。【过程较复杂,这里不做过多描述】
GPT示例:
- 编写一个函数来执行Python代码
#include <Python.h>
jint JNICALL Java_PythonCaller_callPythonCode(JNIEnv *env, jobject obj) {
PyObject *pModule = NULL, *pFunc = NULL, *pResult = NULL;
jint result = 0;
// 初始化Python解释器
Py_Initialize();
// 导入Python模块
pModule = PyImport_ImportModule("test");
if (pModule == NULL) {
PyErr_Print();
goto CLEANUP;
}
// 获取Python函数对象
pFunc = PyObject_GetAttrString(pModule, "get_number");
if (pFunc == NULL || !PyCallable_Check(pFunc)) {
PyErr_Print();
goto CLEANUP;
}
// 调用Python函数并获取结果
pResult = PyObject_CallObject(pFunc, NULL);
if (pResult == NULL) {
PyErr_Print();
goto CLEANUP;
}
// 将Python结果转换为Java整数类型
result = (jint) PyLong_AsLong(pResult);
CLEANUP:
// 释放Python对象和解释器资源
Py_XDECREF(pResult);
Py_XDECREF(pFunc);
Py_XDECREF(pModule);
Py_Finalize();
return result;
}
- 在Java代码中调用该函数
public class PythonCaller {
static {
System.loadLibrary("callpython");
}
public native int callPythonCode();
public static void main(String[] args) {
PythonCaller caller = new PythonCaller();
int result = caller.callPythonCode();
System.out.println("Result: " + result);
}
}
- 将C语言编写的代码编译成动态链接库
gcc -shared -fpic -I /usr/include/python3.6m -o libcallpython.so callpython.c