最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python與Java互操作的五種主流方式

 更新時間:2025年11月04日 09:45:25   作者:榴蓮女士的勺子  
在企業(yè)級應用開發(fā)中,Python 和 Java 常常需要協(xié)同工作——Python 擅長數(shù)據(jù)科學和快速原型開發(fā),Java 則在大型系統(tǒng)和高性能后端方面表現(xiàn)優(yōu)異,本指南將全面介紹 Python 與 Java 互操作的 5 種主流方式,需要的朋友可以參考下

前言

在企業(yè)級應用開發(fā)中,Python 和 Java 常常需要協(xié)同工作——Python 擅長數(shù)據(jù)科學和快速原型開發(fā),Java 則在大型系統(tǒng)和高性能后端方面表現(xiàn)優(yōu)異。本指南將全面介紹 Python 與 Java 互操作的 5 種主流方式,涵蓋從簡單調(diào)用到深度集成的各種場景。

一、Jython:在 JVM 中運行 Python

1.1 基本概念

Jython 是將 Python 實現(xiàn)為 Java 字節(jié)碼的解釋器,允許 Python 代碼直接調(diào)用 Java 類庫。

適用場景

  • 已有 Java 系統(tǒng)需要嵌入 Python 腳本功能
  • 希望復用 Java 生態(tài)中的成熟庫

1.2 實戰(zhàn)示例

# 安裝:pip install jython

from java.util import ArrayList

# 創(chuàng)建 Java ArrayList
java_list = ArrayList()
java_list.add("Java元素")
java_list.add(123)

# 調(diào)用 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 中調(diào)用 Java

2.1 核心機制

JPype 通過 JNI 橋接技術,讓 Python 代碼可以創(chuàng)建 JVM 并調(diào)用 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("測試數(shù)據(jù)")
System.out.println(java_list)  # 輸出: [測試數(shù)據(jù)]

# 調(diào)用靜態(tài)方法
Collections = jpype.JClass("java.util.Collections")
Collections.sort(java_list)

# 關閉 JVM(程序結束前調(diào)用)
jpype.shutdownJVM()

性能提示

  • 避免頻繁啟動/關閉 JVM
  • 使用 @JImplements 實現(xiàn) Java 接口

三、Py4J:雙向網(wǎng)關模式

3.1 架構原理

Py4J 在 Java 進程中運行網(wǎng)關服務器,Python 通過 socket 與之通信。

優(yōu)勢

  • 支持回調(diào)(Java 調(diào)用 Python)
  • 獨立的進程空間更穩(wěn)定

3.2 雙向調(diào)用示例

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()                   # 連接默認網(wǎng)關
math_service = gateway.entry_point        # 獲取Java對象

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

# 回調(diào)示例
class PythonListener:
    def __init__(self, gateway):
        self.gateway = gateway
    
    def notify(self, message):
        print("Java回調(diào):", 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 實現(xiàn)步驟

步驟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 服務端實現(xiàn)

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 客戶端調(diào)用

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 實現(xiàn)示例

步驟1:Java 端準備 native 方法

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

步驟2:生成 C 頭文件

javac -h . NativeBridge.java

步驟3:實現(xiàn) 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");
    
    // 調(diào)用Python函數(shù)
    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:編譯為動態(tài)庫

# 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調(diào)用Java庫有限
Py4J復雜雙向交互
gRPC跨網(wǎng)絡服務調(diào)用
JNI極致性能需求最高最高

決策樹

是否需要雙向調(diào)用?

是 → Py4J 或 gRPC

否 → 進入2

是否主要從Python調(diào)用Java?

是 → JPype

否 → 進入3

是否需要嵌入Python到Java?

是 → Jython

否 → 考慮其他方案

常見問題解決方案

問題1:內(nèi)存泄漏處理

  • JPype:確保及時調(diào)用 jpype.shutdownJVM()
  • Py4J:使用 gateway.close() 釋放資源
  • gRPC:實現(xiàn) __del__ 方法關閉channel

問題2:數(shù)據(jù)類型轉換異常

  • 數(shù)字類型:Java的 long 對應 Python 的 int
  • 容器類型:使用 jpype.JArray 轉換數(shù)組
  • 日期類型:統(tǒng)一轉為時間戳傳輸

問題3:調(diào)試技巧

開啟JPype調(diào)試模式:

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

Py4J日志配置:

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

進階主題

性能優(yōu)化技巧

對象池模式:重用Java對象避免重復創(chuàng)建

# 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)

批量操作:減少跨語言調(diào)用次數(shù)

// 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 的互操作雖然存在挑戰(zhàn),但通過選擇合適的工具和模式,完全可以構建出高效穩(wěn)定的跨語言系統(tǒng)。建議:xnj.gxglhxdec.com

  • 從簡單方案開始,逐步演進
  • 做好接口抽象,降低耦合
  • 建立完善的跨語言測試體系
  • 監(jiān)控性能關鍵指標

隨著 GraalVM 等新技術的發(fā)展,未來兩種語言的互操作將更加無縫。但當前這些成熟方案,已經(jīng)足以支撐大多數(shù)企業(yè)級應用的需求。

以上就是Python與Java互操作的五種主流方式的詳細內(nèi)容,更多關于Python與Java互操作方式的資料請關注腳本之家其它相關文章!

相關文章

  • Python PyQt5學習之自定義信號

    Python PyQt5學習之自定義信號

    PyQ5已經(jīng)自動定義了很多QT自建的信號。但是在實際的使用中為了靈活使用信號與槽機制,可以根據(jù)需要自定義信號。本文就將為大家詳細講講PyQt5自定義信號,感興趣的可以了解一下
    2022-03-03
  • Python自動化運維中服務器性能監(jiān)控與告警詳解

    Python自動化運維中服務器性能監(jiān)控與告警詳解

    這篇文章主要為大家詳細介紹了Python自動化運維中服務器性能監(jiān)控與告警的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2025-04-04
  • Python常見數(shù)據(jù)類型轉換操作示例

    Python常見數(shù)據(jù)類型轉換操作示例

    這篇文章主要介紹了Python常見數(shù)據(jù)類型轉換操作,結合實例形式分析了Python針對列表、集合、元組、字典等數(shù)據(jù)類型轉換的相關操作技巧,需要的朋友可以參考下
    2019-05-05
  • 關于Python?Tkinter?復選框?->Checkbutton

    關于Python?Tkinter?復選框?->Checkbutton

    這篇文章主要介紹了關于Python?Tkinter復選框Checkbutton,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • 如何在python中實現(xiàn)ECDSA你知道嗎

    如何在python中實現(xiàn)ECDSA你知道嗎

    這篇文章主要為大家介紹了python中實現(xiàn)ECDSA,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助,希望能夠給你帶來幫助
    2021-11-11
  • python實現(xiàn)快遞價格查詢系統(tǒng)

    python實現(xiàn)快遞價格查詢系統(tǒng)

    這篇文章主要為大家詳細介紹了python實現(xiàn)快遞價格查詢系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • 通過Python使用saltstack生成服務器資產(chǎn)清單

    通過Python使用saltstack生成服務器資產(chǎn)清單

    人工去對每一臺服務器的硬件信息并記錄早已經(jīng)過去了,無論通過腳本還是自動化工具都是可以進行一次編寫到處抓取的,本文主要使用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內(nèi)置函數(shù)getattr實現(xiàn)分發(fā)模式

    淺談使用Python內(nèi)置函數(shù)getattr實現(xiàn)分發(fā)模式

    這篇文章主要介紹了淺談使用Python內(nèi)置函數(shù)getattr實現(xiàn)分發(fā)模式,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01

最新評論

土默特右旗| 商水县| 双江| 二手房| 遂平县| 长汀县| 丽江市| 花莲县| 海兴县| 双柏县| 共和县| 新丰县| 红河县| 全南县| 宜兴市| 绵阳市| 霍城县| 繁昌县| 昌图县| 长乐市| 潮州市| 澄江县| 贡觉县| 兴化市| 拜泉县| 奈曼旗| 兰考县| 富顺县| 寻甸| 凤阳县| 阳原县| 景德镇市| 达日县| 城口县| 三穗县| 军事| 南雄市| 汉沽区| 元阳县| 新安县| 疏附县|