Python与Java互操作的五种主流方式

 更新时间:2025年11月04日 09:45:25   作者:榴莲女士的勺子  
在企业级应用开发中,Python 和 Java 常常需要协同工作——Python 擅长数据科学和快速原型开发,Java 则在大型系统和高性能后端方面表现优异,本指南将全面介绍 Python 与 Java 互操作的 5 种主流方式,需要的朋友可以参考下

前言

在企业级应用开发中,Python 和 Java 常常需要协同工作——Python 擅长数据科学和快速原型开发,Java 则在大型系统和高性能后端方面表现优异。本指南将全面介绍 Python 与 Java 互操作的 5 种主流方式,涵盖从简单调用到深度集成的各种场景。

一、Jython:在 JVM 中运行 Python

1.1 基本概念

Jython 是将 Python 实现为 Java 字节码的解释器,允许 Python 代码直接调用 Java 类库。

适用场景

  • 已有 Java 系统需要嵌入 Python 脚本功能
  • 希望复用 Java 生态中的成熟库

1.2 实战示例

# 安装:pip install jython

from java.util import ArrayList

# 创建 Java ArrayList
java_list = ArrayList()
java_list.add("Java元素")
java_list.add(123)

# 调用 Java 方法
print(java_list.size())  # 输出: 2

# 继承 Java 类
from javax.swing import JFrame

class MyFrame(JFrame):
    def __init__(self):
        self.setTitle("Jython 示例")
        self.setSize(300, 200)
        self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

frame = MyFrame()
frame.setVisible(True)

限制

  • 仅支持 Python 2.7 语法
  • 无法使用基于 C 的 Python 扩展(如 NumPy)

二、JPype:在 Python 中调用 Java

2.1 核心机制

JPype 通过 JNI 桥接技术,让 Python 代码可以创建 JVM 并调用 Java 类。

适用场景

  • Python 主导的项目需要特定 Java 库功能
  • 需要完整的 Java 8+ 支持

2.2 完整流程示例

# 安装:pip install JPype1

import jpype

# 启动 JVM(指定 jvm.dll 路径)
jpype.startJVM(jpype.getDefaultJVMPath(), 
              "-ea",
              "-Djava.class.path=/path/to/your.jar")

# 导入 Java 类
ArrayList = jpype.JClass("java.util.ArrayList")
System = jpype.JClass("java.lang.System")

# 使用 Java 对象
java_list = ArrayList()
java_list.add("测试数据")
System.out.println(java_list)  # 输出: [测试数据]

# 调用静态方法
Collections = jpype.JClass("java.util.Collections")
Collections.sort(java_list)

# 关闭 JVM(程序结束前调用)
jpype.shutdownJVM()

性能提示

  • 避免频繁启动/关闭 JVM
  • 使用 @JImplements 实现 Java 接口

三、Py4J:双向网关模式

3.1 架构原理

Py4J 在 Java 进程中运行网关服务器,Python 通过 socket 与之通信。

优势

  • 支持回调(Java 调用 Python)
  • 独立的进程空间更稳定

3.2 双向调用示例

Java 服务端

// 添加 Maven 依赖
// <dependency>
//   <groupId>net.sf.py4j</groupId>
//   <artifactId>py4j</artifactId>
//   <version>0.10.9.5</version>
// </dependency>

import py4j.GatewayServer;

public class MathService {
    public int add(int a, int b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        GatewayServer server = new GatewayServer(new MathService());
        server.start();
        System.out.println("Gateway Server Started");
    }
}

Python 客户端

# 安装:pip install py4j

from py4j.java_gateway import JavaGateway

gateway = JavaGateway()                   # 连接默认网关
math_service = gateway.entry_point        # 获取Java对象

result = math_service.add(10, 20)
print(result)  # 输出: 30

# 回调示例
class PythonListener:
    def __init__(self, gateway):
        self.gateway = gateway
    
    def notify(self, message):
        print("Java回调:", message)
        return "Python已处理"

listener = PythonListener(gateway)
gateway.jvm.System.setProperty("python.listener", 
                              gateway.jvm.py4j.GatewayServer.DEFAULT_PYTHON_PROXY_PORT)

四、gRPC 跨语言通信

4.1 方案特点

  • 基于 Protocol Buffers 的 IDL
  • 支持流式通信
  • 语言中立

4.2 实现步骤

步骤1:定义 proto 文件

syntax = "proto3";

service DataProcessor {
  rpc Process (DataRequest) returns (DataResponse);
}

message DataRequest {
  string content = 1;
  int32 priority = 2;
}

message DataResponse {
  bool success = 1;
  string result = 2;
}

步骤2:生成代码

# Python 端
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. data.proto

# Java 端(Maven配置)
<build>
  <extensions>
    <extension>
      <groupId>kr.motd.maven</groupId>
      <artifactId>os-maven-plugin</artifactId>
      <version>1.6.2</version>
    </extension>
  </extensions>
  <plugins>
    <plugin>
      <groupId>org.xolstice.maven.plugins</groupId>
      <artifactId>protobuf-maven-plugin</artifactId>
      <version>0.6.1</version>
      <configuration>
        <protocArtifact>com.google.protobuf:protoc:3.19.2:exe:${os.detected.classifier}</protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.47.0:exe:${os.detected.classifier}</pluginArtifact>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>compile-custom</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

步骤3:Java 服务端实现

public class DataServiceImpl extends DataProcessorGrpc.DataProcessorImplBase {
    @Override
    public void process(DataRequest request, 
                       StreamObserver<DataResponse> responseObserver) {
        System.out.println("收到请求: " + request.getContent());
        
        DataResponse response = DataResponse.newBuilder()
            .setSuccess(true)
            .setResult("Processed: " + request.getContent().toUpperCase())
            .build();
        
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

// 启动服务器
Server server = ServerBuilder.forPort(50051)
    .addService(new DataServiceImpl())
    .build()
    .start();

步骤4:Python 客户端调用

import grpc
import data_pb2
import data_pb2_grpc

channel = grpc.insecure_channel('localhost:50051')
stub = data_pb2_grpc.DataProcessorStub(channel)

response = stub.Process(data_pb2.DataRequest(
    content="hello grpc",
    priority=1
))

print(response.result)  # 输出: Processed: HELLO GRPC

五、JNI 原生扩展(高级方案)

5.1 架构设计

图表

代码

5.2 实现示例

步骤1:Java 端准备 native 方法

public class NativeBridge {
    static {
        System.loadLibrary("nativebridge");
    }
    
    public native String processData(String input);
}

步骤2:生成 C 头文件

javac -h . NativeBridge.java

步骤3:实现 C 层逻辑

#include <jni.h>
#include "NativeBridge.h"
#include <Python.h>

JNIEXPORT jstring JNICALL Java_NativeBridge_processData(
    JNIEnv *env, jobject obj, jstring input) {
    
    const char *str = (*env)->GetStringUTFChars(env, input, 0);
    
    // 初始化Python解释器
    Py_Initialize();
    PyObject *pModule = PyImport_ImportModule("data_processor");
    PyObject *pFunc = PyObject_GetAttrString(pModule, "process");
    
    // 调用Python函数
    PyObject *pArgs = PyTuple_Pack(1, PyUnicode_FromString(str));
    PyObject *pResult = PyObject_CallObject(pFunc, pArgs);
    
    const char *result = PyUnicode_AsUTF8(pResult);
    
    // 清理资源
    Py_DECREF(pArgs);
    Py_DECREF(pResult);share.aalatni.cn
    Py_Finalize();
    
    return (*env)->NewStringUTF(env, result);
}

步骤4:编译为动态库

# Linux示例
gcc -shared -fPIC -I${JAVA_HOME}/include \
    -I${JAVA_HOME}/include/linux \
    -I/usr/include/python3.8 \
    -o libnativebridge.so NativeBridge.c \
    -lpython3.8

方案对比与选型建议

方案适用场景性能复杂度双向通信
Jython嵌入Python到Java应用
JPypePython调用Java库有限
Py4J复杂双向交互
gRPC跨网络服务调用
JNI极致性能需求最高最高

决策树

是否需要双向调用?

是 → Py4J 或 gRPC

否 → 进入2

是否主要从Python调用Java?

是 → JPype

否 → 进入3

是否需要嵌入Python到Java?

是 → Jython

否 → 考虑其他方案

常见问题解决方案

问题1:内存泄漏处理

  • JPype:确保及时调用 jpype.shutdownJVM()
  • Py4J:使用 gateway.close() 释放资源
  • gRPC:实现 __del__ 方法关闭channel

问题2:数据类型转换异常

  • 数字类型:Java的 long 对应 Python 的 int
  • 容器类型:使用 jpype.JArray 转换数组
  • 日期类型:统一转为时间戳传输

问题3:调试技巧

开启JPype调试模式:

jpype.startJVM(..., "-Djpype.debug=True")

Py4J日志配置:

System.setProperty("py4j.logging", "py4j.logging.ConsoleLogger")

进阶主题

性能优化技巧

对象池模式:重用Java对象避免重复创建

# JPype对象池示例
class ObjectPool:aiqiyi.aalatni.cn
    def __init__(self, j_class, size=10):
        self.pool = [j_class() for _ in range(size)]
        
    def acquire(self):
        return self.pool.pop() if self.pool else None
        
    def release(self, obj):
        self.pool.append(obj)

批量操作:减少跨语言调用次数

// Java端提供批量接口
public List<String> batchProcess(List<String> inputs) {
    return inputs.stream().map(this::process).collect(Collectors.toList());
}

安全注意事项

gRPC:启用TLS加密

# Python客户端
creds = grpc.ssl_channel_credentials()tenxun.aalatni.cn
channel = grpc.secure_channel('localhost:50051', creds)

Py4J:设置白名单

GatewayServer server = new GatewayServer(
    new MathService(),
    GatewayServer.DEFAULT_PORT,
    GatewayServer.DEFAULT_CONNECT_TIMEOUT,
    GatewayServer.DEFAULT_READ_TIMEOUT,
    new String[] {"192.168.1.*"}  // IP白名单
);

结语

Python 与 Java 的互操作虽然存在挑战,但通过选择合适的工具和模式,完全可以构建出高效稳定的跨语言系统。建议:xnj.gxglhxdec.com

  • 从简单方案开始,逐步演进
  • 做好接口抽象,降低耦合
  • 建立完善的跨语言测试体系
  • 监控性能关键指标

随着 GraalVM 等新技术的发展,未来两种语言的互操作将更加无缝。但当前这些成熟方案,已经足以支撑大多数企业级应用的需求。

以上就是Python与Java互操作的五种主流方式的详细内容,更多关于Python与Java互操作方式的资料请关注脚本之家其它相关文章!

相关文章

  • Python PyQt5学习之自定义信号

    Python PyQt5学习之自定义信号

    PyQ5已经自动定义了很多QT自建的信号。但是在实际的使用中为了灵活使用信号与槽机制,可以根据需要自定义信号。本文就将为大家详细讲讲PyQt5自定义信号,感兴趣的可以了解一下
    2022-03-03
  • Python自动化运维中服务器性能监控与告警详解

    Python自动化运维中服务器性能监控与告警详解

    这篇文章主要为大家详细介绍了Python自动化运维中服务器性能监控与告警的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2025-04-04
  • Python常见数据类型转换操作示例

    Python常见数据类型转换操作示例

    这篇文章主要介绍了Python常见数据类型转换操作,结合实例形式分析了Python针对列表、集合、元组、字典等数据类型转换的相关操作技巧,需要的朋友可以参考下
    2019-05-05
  • 关于Python Tkinter 复选框 ->Checkbutton

    关于Python Tkinter 复选框 ->Checkbutton

    这篇文章主要介绍了关于Python Tkinter复选框Checkbutton,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 如何在python中实现ECDSA你知道吗

    如何在python中实现ECDSA你知道吗

    这篇文章主要为大家介绍了python中实现ECDSA,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助,希望能够给你带来帮助
    2021-11-11
  • python实现快递价格查询系统

    python实现快递价格查询系统

    这篇文章主要为大家详细介绍了python实现快递价格查询系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 通过Python使用saltstack生成服务器资产清单

    通过Python使用saltstack生成服务器资产清单

    人工去对每一台服务器的硬件信息并记录早已经过去了,无论通过脚本还是自动化工具都是可以进行一次编写到处抓取的,本文主要使用saltstack作为使用工具,然后利用其提供的APi编写所需的Python脚本
    2016-03-03
  • Python 模拟死锁的常见实例详解

    Python 模拟死锁的常见实例详解

    这篇文章主要为大家介绍了Python 模拟死锁的常见实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 解决redis与Python交互取出来的是bytes类型的问题

    解决redis与Python交互取出来的是bytes类型的问题

    这篇文章主要介绍了解决redis与Python交互取出来的是bytes类型的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 浅谈使用Python内置函数getattr实现分发模式

    浅谈使用Python内置函数getattr实现分发模式

    这篇文章主要介绍了浅谈使用Python内置函数getattr实现分发模式,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01

最新评论