欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java調(diào)用Python腳本實(shí)現(xiàn)HelloWorld的示例詳解

 更新時(shí)間:2025年08月17日 08:57:47   作者:程序員丘山  
作為程序員,我們經(jīng)常會(huì)遇到需要在Java項(xiàng)目中調(diào)用Python腳本的場(chǎng)景,下面我們來(lái)看看如何從基礎(chǔ)到進(jìn)階,一步步實(shí)現(xiàn)Java與Python的"HelloWorld"交互吧

作為程序員,我們經(jīng)常會(huì)遇到需要在Java項(xiàng)目中調(diào)用Python腳本的場(chǎng)景??赡苁菫榱藦?fù)用現(xiàn)成的Python工具庫(kù),也可能是需要利用Python在數(shù)據(jù)處理上的優(yōu)勢(shì)。本文不聊太多理論,直接上手三種實(shí)用的調(diào)用方式,從基礎(chǔ)到進(jìn)階,一步步實(shí)現(xiàn)Java與Python的"HelloWorld"交互。

一、環(huán)境準(zhǔn)備

在開始之前,確保你的開發(fā)環(huán)境滿足以下條件:

  • Java環(huán)境:JDK 8+(推薦11),配置好JAVA_HOME
  • Python環(huán)境:Python 3.6+,配置好PATH(命令行輸入python --version能正常顯示版本)
  • 開發(fā)工具:任意IDE,文本編輯器(用于寫Python腳本)

驗(yàn)證環(huán)境的小技巧:

# 檢查Java
java -version
# 檢查Python
python --version  # 或python3 --version(根據(jù)系統(tǒng)配置)

如果Python命令無(wú)法識(shí)別,大概率是沒(méi)配置環(huán)境變量。Windows用戶可以在"設(shè)置-系統(tǒng)-關(guān)于-高級(jí)系統(tǒng)設(shè)置-環(huán)境變量"中添加Python安裝路徑;Linux/Mac用戶可以在~/.bashrc~/.zshrc中添加export PATH=$PATH:/usr/local/python3/bin(替換為實(shí)際路徑)。

二、基礎(chǔ)調(diào)用:使用 Runtime.exec()

這是最直接的調(diào)用方式,通過(guò)Java的Runtime類啟動(dòng)Python進(jìn)程執(zhí)行腳本。適合簡(jiǎn)單場(chǎng)景,無(wú)需復(fù)雜交互。

2.1 實(shí)現(xiàn)步驟

步驟1:編寫Python腳本

創(chuàng)建hello.py,放在Java項(xiàng)目的根目錄(或指定絕對(duì)路徑):

# 接收J(rèn)ava傳遞的參數(shù)
import sys

if __name__ == "__main__":
    # 獲取Java傳入的參數(shù)(第0個(gè)參數(shù)是腳本名)
    name = sys.argv[1] if len(sys.argv) > 1 else "World"
    # 輸出結(jié)果(會(huì)被Java捕獲)
    print(f"Hello, {name}! From Python")

步驟2:編寫Java調(diào)用代碼

創(chuàng)建JavaCallPythonByRuntime.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class JavaCallPythonByRuntime {
    public static void main(String[] args) {
        // 1. 定義Python腳本路徑和參數(shù)
        String pythonScriptPath = "hello.py";
        String param = "Java";  // 要傳遞給Python的參數(shù)

        // 2. 構(gòu)建命令數(shù)組(推薦用數(shù)組形式,避免空格問(wèn)題)
        String[] cmd = new String[]{"python", pythonScriptPath, param};

        try {
            // 3. 啟動(dòng)Python進(jìn)程
            Process process = Runtime.getRuntime().exec(cmd);

            // 4. 讀取Python的輸出(必須讀取,否則可能導(dǎo)致進(jìn)程阻塞)
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, "UTF-8")  // 指定編碼,避免中文亂碼
            );
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("Python輸出:" + line);
            }

            // 5. 等待進(jìn)程執(zhí)行完成并獲取退出碼(0表示成功)
            int exitCode = process.waitFor();
            System.out.println("進(jìn)程退出碼:" + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.2 代碼解析

  • 命令數(shù)組:用String[]而不是單字符串,避免路徑或參數(shù)包含空格時(shí)解析錯(cuò)誤(比如腳本路徑是D:\my script\hello.py)。
  • 輸入流處理:Python的print輸出會(huì)寫入進(jìn)程的輸入流,Java必須讀取這些內(nèi)容,否則緩沖區(qū)滿了會(huì)導(dǎo)致進(jìn)程卡住。
  • 編碼設(shè)置InputStreamReader指定UTF-8,解決Windows系統(tǒng)下默認(rèn)GBK編碼導(dǎo)致的中文亂碼問(wèn)題。
  • 退出碼process.waitFor()返回的退出碼能幫我們判斷腳本是否正常執(zhí)行(非0通常表示出錯(cuò))。

三、進(jìn)階調(diào)用:使用 ProcessBuilder

ProcessBuilder是JDK 5引入的類,比Runtime.exec()更靈活,支持設(shè)置工作目錄、環(huán)境變量等,適合復(fù)雜場(chǎng)景。

3.1 實(shí)現(xiàn)步驟

步驟1:復(fù)用Python腳本

繼續(xù)使用前面的hello.py,稍作修改支持從環(huán)境變量讀取配置:

import sys
import os

if __name__ == "__main__":
    name = sys.argv[1] if len(sys.argv) > 1 else "World"
    # 讀取Java設(shè)置的環(huán)境變量
    app_name = os.getenv("APP_NAME", "UnknownApp")
    print(f"[{app_name}] Hello, {name}! From Python")

步驟2:編寫Java代碼

創(chuàng)建JavaCallPythonByProcessBuilder.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

public class JavaCallPythonByProcessBuilder {
    public static void main(String[] args) {
        try {
            // 1. 創(chuàng)建ProcessBuilder,指定命令和參數(shù)
            ProcessBuilder pb = new ProcessBuilder(
                "python", "hello.py", "JavaDeveloper"
            );

            // 2. 設(shè)置工作目錄(腳本所在目錄,不設(shè)置則默認(rèn)當(dāng)前目錄)
            pb.directory(new java.io.File("./scripts"));  // 假設(shè)腳本放在scripts子目錄

            // 3. 設(shè)置環(huán)境變量(給Python腳本傳遞配置)
            Map<String, String> env = pb.environment();
            env.put("APP_NAME", "JavaCallPythonDemo");

            // 4. 重定向錯(cuò)誤流到輸入流(方便統(tǒng)一處理輸出和錯(cuò)誤)
            pb.redirectErrorStream(true);

            // 5. 啟動(dòng)進(jìn)程
            Process process = pb.start();

            // 6. 讀取輸出
            try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream(), "UTF-8")
            )) {
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println("Python輸出:" + line);
                }
            }

            // 7. 等待進(jìn)程完成
            int exitCode = process.waitFor();
            System.out.println("進(jìn)程退出碼:" + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.2 代碼解析

  • 工作目錄pb.directory()指定腳本所在目錄,避免路徑混亂。比如腳本放在./scripts,就不用寫全路徑了。
  • 環(huán)境變量:通過(guò)pb.environment()設(shè)置的變量,Python可以用os.getenv()獲取,適合傳遞配置信息(如API密鑰、環(huán)境標(biāo)識(shí))。
  • 錯(cuò)誤流重定向redirectErrorStream(true)將錯(cuò)誤信息合并到輸入流,不用單獨(dú)處理getErrorStream(),簡(jiǎn)化代碼。
  • 資源自動(dòng)關(guān)閉try-with-resources語(yǔ)法確保BufferedReader自動(dòng)關(guān)閉,避免資源泄漏。

四、服務(wù)化調(diào)用:HTTP接口通信

當(dāng)Java和Python需要頻繁交互,或需要跨服務(wù)器調(diào)用時(shí),將Python腳本封裝成HTTP服務(wù)是更優(yōu)的方案。這里用Flask搭建簡(jiǎn)單接口。

4.1 實(shí)現(xiàn)步驟

步驟1:搭建Python HTTP服務(wù)

首先安裝Flask:

pip install flask

創(chuàng)建hello_service.py

from flask import Flask, request

app = Flask(__name__)

@app.route('/hello', methods=['GET'])
def hello():
    # 從請(qǐng)求參數(shù)獲取name
    name = request.args.get('name', 'World')
    return f"Hello, {name}! From Python Service"

if __name__ == '__main__':
    # 啟動(dòng)服務(wù),允許外部訪問(wèn)
    app.run(host='0.0.0.0', port=5000, debug=True)

步驟2:編寫Java HTTP客戶端

創(chuàng)建JavaCallPythonByHttp.java,使用JDK自帶的HttpClient(JDK 11+):

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

public class JavaCallPythonByHttp {
    public static void main(String[] args) {
        // 1. 創(chuàng)建HttpClient
        HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(5))
                .build();

        // 2. 構(gòu)建請(qǐng)求(Python服務(wù)地址)
        String name = "JavaHttpClient";
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://localhost:5000/hello?name=" + name))
                .timeout(Duration.ofSeconds(3))
                .GET()
                .build();

        try {
            // 3. 發(fā)送請(qǐng)求并獲取響應(yīng)
            HttpResponse<String> response = client.send(
                request, HttpResponse.BodyHandlers.ofString()
            );

            // 4. 處理響應(yīng)
            if (response.statusCode() == 200) {
                System.out.println("Python服務(wù)響應(yīng):" + response.body());
            } else {
                System.err.println("請(qǐng)求失敗,狀態(tài)碼:" + response.statusCode());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.2 代碼解析

  • Python服務(wù):用Flask創(chuàng)建/hello接口,通過(guò)request.args獲取Java傳遞的參數(shù),返回字符串。debug=True方便開發(fā)時(shí)自動(dòng)重啟。
  • Java客戶端:JDK 11的HttpClient比傳統(tǒng)的HttpURLConnection更簡(jiǎn)潔,支持異步調(diào)用(sendAsync),這里用同步send更直觀。
  • 跨機(jī)器調(diào)用:只要Python服務(wù)的host設(shè)為0.0.0.0,并開放5000端口,Java可以通過(guò)服務(wù)器IP訪問(wèn)(如http://192.168.1.100:5000/hello)。

五、三種方法對(duì)比與選擇建議

調(diào)用方式優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
Runtime.exec()簡(jiǎn)單直接,無(wú)需額外依賴靈活性差,不便于設(shè)置環(huán)境和工作目錄簡(jiǎn)單腳本,一次性調(diào)用
ProcessBuilder支持環(huán)境變量、工作目錄,錯(cuò)誤流合并代碼稍復(fù)雜,仍需處理進(jìn)程通信復(fù)雜腳本,需要傳遞配置信息
HTTP接口松耦合,支持跨機(jī)器,可異步需要維護(hù)HTTP服務(wù),有網(wǎng)絡(luò)開銷頻繁交互,分布式系統(tǒng),跨語(yǔ)言調(diào)用

實(shí)際開發(fā)中:

  • 臨時(shí)腳本調(diào)用用ProcessBuilder;
  • 長(zhǎng)期維護(hù)的功能推薦HTTP服務(wù)化,便于獨(dú)立部署和升級(jí);
  • 避免在高并發(fā)場(chǎng)景用進(jìn)程調(diào)用(頻繁創(chuàng)建銷毀進(jìn)程開銷大)。

六、避坑指南

1.路徑中的空格:Windows路徑如果有空格(如Program Files),用ProcessBuilder時(shí)會(huì)自動(dòng)處理,但用Runtime.exec()單字符串命令可能出錯(cuò),推薦始終用數(shù)組形式傳參。

2.Python輸出緩沖區(qū):如果Python腳本輸出大量?jī)?nèi)容,會(huì)先存到緩沖區(qū),Java讀取不及時(shí)會(huì)導(dǎo)致腳本卡住。解決方法:

  • Python中手動(dòng)刷新緩沖區(qū):print(..., flush=True)
  • Java中用線程異步讀取輸出

3.版本兼容:確保Java調(diào)用的Python版本和開發(fā)時(shí)一致(比如同時(shí)用Python 3.9),避免語(yǔ)法不兼容問(wèn)題。

4.異常捕獲:生產(chǎn)環(huán)境中必須捕獲所有可能的異常(IOException、InterruptedException等),并記錄日志,方便排查問(wèn)題。

總結(jié)

本文介紹了三種Java調(diào)用Python腳本實(shí)現(xiàn)HelloWorld的方法,從簡(jiǎn)單的進(jìn)程調(diào)用到服務(wù)化通信,覆蓋了不同場(chǎng)景的需求。核心是根據(jù)項(xiàng)目實(shí)際情況選擇合適的方案:簡(jiǎn)單場(chǎng)景用ProcessBuilder,分布式場(chǎng)景用HTTP接口。

實(shí)際開發(fā)中,建議先做小范圍測(cè)試,重點(diǎn)關(guān)注參數(shù)傳遞、異常處理和性能表現(xiàn)。只要把這些細(xì)節(jié)處理好,Java和Python的協(xié)作會(huì)非常順暢。

到此這篇關(guān)于Java調(diào)用Python腳本實(shí)現(xiàn)HelloWorld的示例詳解的文章就介紹到這了,更多相關(guān)Java調(diào)用Python腳本內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法

    Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)XML格式與JSON格式互相轉(zhuǎn)換的方法,方法通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),選擇使用哪種格式通常取決于項(xiàng)目的需求和上下文,所以格式轉(zhuǎn)換就成了我們必備的技能,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧
    2023-10-10
  • JavaWeb搭建網(wǎng)上圖書商城畢業(yè)設(shè)計(jì)

    JavaWeb搭建網(wǎng)上圖書商城畢業(yè)設(shè)計(jì)

    這篇文章主要介紹了JavaWeb搭建網(wǎng)上圖書商城框架,特別適合正在為網(wǎng)上商城畢業(yè)設(shè)計(jì)煩惱的同學(xué),需要的朋友可以參考下
    2015-11-11
  • Java中的Phaser使用詳解

    Java中的Phaser使用詳解

    這篇文章主要介紹了Java中的Phaser使用詳解,與其他障礙不同,注冊(cè)在phaser上進(jìn)行同步的parties數(shù)量可能會(huì)隨時(shí)間變化,任務(wù)可以隨時(shí)進(jìn)行注冊(cè),需要的朋友可以參考下
    2023-11-11
  • Eclipse將Maven項(xiàng)目打成jar包的方法

    Eclipse將Maven項(xiàng)目打成jar包的方法

    這篇文章主要介紹了Eclipse將Maven項(xiàng)目打成jar包的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2007-09-09
  • Java實(shí)現(xiàn)蘿卜勇者游戲的示例代碼

    Java實(shí)現(xiàn)蘿卜勇者游戲的示例代碼

    《蘿卜勇者》是由國(guó)內(nèi)玩家自制的一款獨(dú)立游戲,玩家扮演蘿卜勇士闖關(guān),打敗各種邪惡的敵人,獲得最后的勝利。本文將利用Java實(shí)現(xiàn)這一游戲,感興趣的可以了解一下
    2022-02-02
  • Java?將PDF轉(zhuǎn)為HTML時(shí)保存到流的方法和步驟

    Java?將PDF轉(zhuǎn)為HTML時(shí)保存到流的方法和步驟

    本文介紹如何通過(guò)Java后端程序代碼將PDF文件轉(zhuǎn)為HTML,并將轉(zhuǎn)換后的HTML文件保存到流,下面是實(shí)現(xiàn)轉(zhuǎn)換的方法和步驟,感興趣的朋友一起看看吧
    2022-01-01
  • springboot項(xiàng)目啟動(dòng)的時(shí)候參數(shù)無(wú)效的解決

    springboot項(xiàng)目啟動(dòng)的時(shí)候參數(shù)無(wú)效的解決

    這篇文章主要介紹了springboot項(xiàng)目啟動(dòng)的時(shí)候參數(shù)無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java.lang.IllegalStateException異常原因和解決辦法

    java.lang.IllegalStateException異常原因和解決辦法

    這篇文章主要給大家介紹了關(guān)于java.lang.IllegalStateException異常原因和解決辦法,IllegalStateException是Java標(biāo)準(zhǔn)庫(kù)中的一個(gè)異常類,通常表示在不合適或無(wú)效的情況下執(zhí)行了某個(gè)方法或操作,需要的朋友可以參考下
    2023-07-07
  • 永中文檔在線轉(zhuǎn)換服務(wù)Swagger調(diào)用說(shuō)明

    永中文檔在線轉(zhuǎn)換服務(wù)Swagger調(diào)用說(shuō)明

    這篇文章主要為大家介紹了永中文檔在線轉(zhuǎn)換服務(wù)Swagger調(diào)用說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 解決若依微服務(wù)框架啟動(dòng)報(bào)錯(cuò)的問(wèn)題

    解決若依微服務(wù)框架啟動(dòng)報(bào)錯(cuò)的問(wèn)題

    Invalid bound statement錯(cuò)誤通常由MyBatis映射文件未正確加載或Nacos配置未讀取導(dǎo)致,需檢查XML的namespace與方法ID是否匹配,確認(rèn)資源目錄配置,確保bootstrap.yml中Nacos配置路徑正確加載
    2025-08-08

最新評(píng)論