一、py4j 库概述
py4j 是一款专注于Python 与 Java 双向通信、互操作的开源库,能够让 Python 代码直接调用 Java 对象、方法,也可让 Java 调用 Python 代码,基于 Socket 通信实现跨语言交互,无需额外编译。其采用 BSD 开源许可,使用灵活无商业限制。优点是接入简单、无侵入、支持完整 Java 生态,缺点是依赖网络通信,存在少量性能开销,不适合超高频低延迟场景。

二、py4j 核心工作原理
py4j 本质是一套跨语言的 RPC 通信框架,核心运行流程分为两步:
- 启动 Java 端的 GatewayServer 网关服务,监听指定端口,作为通信桥梁;
- Python 端通过 GatewayClient 连接该服务,借助协议解析,把 Python 调用转为 Java 指令执行,再把结果返回 Python。
整个过程对开发者透明,无需关心底层序列化、网络传输,只需像调用本地代码一样使用跨语言对象,既支持 Java 标准库,也兼容自定义 Java 类、jar 包依赖,是 Python 对接 Java 系统的轻量化方案。
三、py4j 安装方法
py4j 安装仅需通过 pip 执行指令,Python 与 Java 环境均需配置,且 Java 需配置环境变量:
1. Python 端安装
打开命令行执行:
pip install py4j
安装完成后,可通过以下代码验证安装结果:
import py4j
print(py4j.__version__)
执行后输出版本号,即代表 Python 端安装成功。
2. Java 端依赖配置
Java 端无需手动安装,只需引入 py4j 的 jar 包,有两种方式:
- Maven 项目:在 pom.xml 中添加依赖
<dependency>
<groupId>net.sf.py4j</groupId>
<artifactId>py4j</artifactId>
<version>0.10.9.7</version>
</dependency>
- 普通 Java 项目:从官网下载 py4j 的 jar 包,添加到项目构建路径即可。
四、基础使用:Python 调用 Java 标准库
这是 py4j 最常用的场景,无需编写自定义 Java 代码,直接调用 Java 内置类,快速体验跨语言调用。
1. Java 端启动网关服务
新建 Java 类,启动 GatewayServer,代码如下:
import py4j.GatewayServer;
public class JavaGateway {
public static void main(String[] args) {
// 启动网关服务,默认端口 25333
GatewayServer gatewayServer = new GatewayServer();
gatewayServer.start();
System.out.println("py4j 网关服务启动成功");
}
}
运行该 Java 程序,控制台输出启动成功,服务进入监听状态。
2. Python 端调用 Java 类
Python 连接网关后,可直接调用 Java 工具类,示例调用 ArrayList、String、Math 类:
from py4j.java_gateway import JavaGateway
# 连接 Java 网关服务
gateway = JavaGateway()
# 1. 调用 Java ArrayList 集合
java_list = gateway.jvm.java.util.ArrayList()
java_list.add("Python")
java_list.add("Java")
java_list.add("py4j")
print("Java ArrayList 内容:", java_list)
print("ArrayList 长度:", java_list.size())
# 2. 调用 Java String 方法
java_str = gateway.jvm.java.lang.String("Hello py4j")
print("字符串转大写:", java_str.toUpperCase())
# 3. 调用 Java Math 工具类
math_result = gateway.jvm.java.lang.Math.sqrt(64)
print("64 的平方根:", math_result)
代码说明
JavaGateway():自动连接本地默认端口的 Java 网关,无需手动配置地址;gateway.jvm:核心入口,通过它访问所有 Java 类;- 调用方式与 Java 完全一致,支持方法传参、属性获取,降低学习成本。
运行 Python 代码,可正常输出 Java 方法执行结果,实现基础跨语言调用。
五、进阶使用:Python 调用自定义 Java 类
实际开发中,更多是调用自定义 Java 业务类,py4j 完美支持自定义类、对象方法、静态方法调用。
1. 编写自定义 Java 类
新建用户工具类,包含成员方法、静态方法、带参构造方法:
public class UserTool {
private String username;
// 无参构造
public UserTool() {}
// 带参构造
public UserTool(String username) {
this.username = username;
}
// 成员方法
public String sayHello() {
return "Hello, " + username;
}
// 带参成员方法
public int add(int a, int b) {
return a + b;
}
// 静态方法
public static String staticMethod() {
return "这是 Java 静态方法";
}
}
2. Java 端启动服务(注册自定义类)
无需额外注册,启动网关后,自定义类会自动加载,Python 可直接访问:
import py4j.GatewayServer;
public class CustomJavaServer {
public static void main(String[] args) {
GatewayServer server = new GatewayServer();
server.start();
System.out.println("自定义 Java 服务启动成功");
}
}
运行该 Java 程序,确保自定义类已编译生效。
3. Python 调用自定义 Java 类
from py4j.java_gateway import JavaGateway
gateway = JavaGateway()
# 1. 创建自定义 Java 类对象(无参构造)
user_tool = gateway.jvm.UserTool()
# 调用带参构造
user_tool2 = gateway.jvm.UserTool("py4j用户")
# 2. 调用成员方法
hello_msg = user_tool2.sayHello()
print(hello_msg)
# 3. 调用带参方法
add_result = user_tool2.add(10, 20)
print("10 + 20 =", add_result)
# 4. 调用静态方法
static_msg = gateway.jvm.UserTool.staticMethod()
print(static_msg)
代码说明
- 自定义类无需特殊注解,py4j 自动反射获取类结构;
- 支持构造方法、成员方法、静态方法全场景调用,与 Java 编码习惯一致;
- 可传递 int、String、集合等基础类型参数,自动完成类型转换。
运行后可正常获取自定义 Java 类的执行结果,满足业务代码调用需求。
六、高级使用:Java 调用 Python 代码
py4j 支持双向通信,除了 Python 调 Java,还能让 Java 主动调用 Python 函数、对象,实现双向交互。
1. Python 端编写可调用代码
from py4j.java_gateway import JavaGateway
# 启动 Python 网关,允许 Java 调用
gateway = JavaGateway()
python_gateway = gateway.gateway_server
# 定义 Python 函数,供 Java 调用
def python_add(a, b):
print("Python 函数被调用")
return a + b
def python_message(msg):
return "Python 接收:" + msg
# 注册 Python 对象,让 Java 访问
class PythonDemo:
def test_method(self):
return "Python 类方法执行成功"
# 注册实例
python_demo = PythonDemo()
gateway.entry_point.python_demo = python_demo
gateway.entry_point.python_add = python_add
gateway.entry_point.python_message = python_message
print("Python 服务已启动,等待 Java 调用...")
# 保持程序运行
while True:
pass
2. Java 端调用 Python 代码
import py4j.GatewayServer;
public class JavaCallPython {
public static void main(String[] args) {
GatewayServer server = new GatewayServer();
server.start();
// 获取 Python 入口点,调用 Python 函数
Object entryPoint = server.getGateway().getEntryPoint();
try {
// 调用 Python 加法函数
int sum = (int) entryPoint.getClass()
.getMethod("python_add", int.class, int.class)
.invoke(entryPoint, 30, 50);
System.out.println("Java 调用 Python 加法结果:" + sum);
// 调用 Python 字符串方法
String msg = (String) entryPoint.getClass()
.getMethod("python_message", String.class)
.invoke(entryPoint, "Java 消息");
System.out.println(msg);
// 调用 Python 类方法
Object pythonDemo = entryPoint.getClass()
.getField("python_demo")
.get(entryPoint);
String testResult = (String) pythonDemo.getClass()
.getMethod("test_method")
.invoke(pythonDemo);
System.out.println(testResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码说明
- Python 端通过
entry_point注册函数、对象,暴露给 Java 调用; - Java 端通过反射获取 Python 注册的内容,执行对应逻辑;
- 双向调用模式,可实现 Python 与 Java 系统的无缝协同,适合老旧 Java 系统升级。
七、实际业务案例:Python 数据分析对接 Java 业务系统
模拟企业真实场景:Java 负责业务数据存储,Python 负责数据分析,通过 py4j 实现数据互通。
1. Java 端:提供数据查询类
import java.util.ArrayList;
import java.util.List;
// 模拟业务数据查询类
public class DataService {
// 模拟查询用户年龄数据
public List<Integer> getUserAges() {
List<Integer> ages = new ArrayList<>();
ages.add(22);
ages.add(25);
ages.add(28);
ages.add(30);
ages.add(35);
return ages;
}
// 模拟查询用户姓名
public List<String> getUserNames() {
List<String> names = new ArrayList<>();
names.add("张三");
names.add("李四");
names.add("王五");
names.add("赵六");
names.add("钱七");
return names;
}
}
2. Java 启动服务
import py4j.GatewayServer;
public class DataServer {
public static void main(String[] args) {
GatewayServer server = new GatewayServer();
server.start();
System.out.println("业务数据服务启动成功");
}
}
3. Python 端:获取数据并做数据分析
from py4j.java_gateway import JavaGateway
# 连接 Java 服务
gateway = JavaGateway()
data_service = gateway.jvm.DataService()
# 1. 获取 Java 业务数据
ages = data_service.getUserAges()
names = data_service.getUserNames()
# 转换为 Python 列表,方便处理
age_list = [age for age in ages]
name_list = [name for name in names]
print("用户姓名:", name_list)
print("用户年龄:", age_list)
# 2. Python 数据分析:计算年龄平均值、最大值、最小值
avg_age = sum(age_list) / len(age_list)
max_age = max(age_list)
min_age = min(age_list)
print("平均年龄:", round(avg_age, 2))
print("最大年龄:", max_age)
print("最小年龄:", min_age)
# 3. 把分析结果返回给 Java(演示双向交互)
def send_analysis_result(avg, max_age, min_age):
return f"分析结果:平均年龄{avg},最大{max_age},最小{min_age}"
# 注册方法供 Java 调用
gateway.entry_point.send_result = send_analysis_result
print("分析完成,结果已暴露给 Java 端")
# 保持运行
while True:
pass
案例价值
该案例贴合企业实际开发场景,Java 负责稳定的业务逻辑、数据管理,Python 发挥数据分析、机器学习优势,通过 py4j 打通两种语言的壁垒,无需重构现有系统,低成本实现功能扩展,既保留 Java 系统的稳定性,又利用 Python 提升数据处理能力。
八、py4j 优缺点总结
优点
- 接入成本极低,无需修改原有 Java 代码,无侵入式集成;
- 支持 Python 与 Java 双向调用,适用场景广泛;
- 兼容所有 Java 类、第三方 jar 包,无需额外适配;
- 开源免费,BSD 许可可用于商业项目;
- 语法贴近原生语言,学习门槛低,新手易上手。
缺点
- 基于 Socket 通信,存在网络开销,不适合超高频调用;
- 复杂对象序列化需要手动处理,部分特殊类型支持有限;
- 分布式场景下需自行处理服务部署、端口占用问题。
九、相关资源
- Pypi 地址:https://pypi.org/project/py4j/
- Github 地址:https://github.com/py4j/py4j
- 官方文档地址:https://www.py4j.org/
关注我,每天分享一个实用的Python自动化工具。
