写在前面
在微服务架构大行其道的今天,对于将程序进行嵌套调用的做法其实并不可取,甚至显得有些愚蠢。当然,之所以要面对这个问题,或许是因为一些历史原因,或者仅仅是为了简单。恰好我在项目中就遇到了这个问题,需要在Java程序中调用Python程序。关于在Java中调用Python程序的实现,根据不同的用途可以使用多种不同的方法,在这里就将在Java中调用Python程序的方式做一个总结。
直接通过Runtime进行调用
我们知道,在Java中如果需要调用第三方程序,可以直接通过Runtime实现,这也是最直接最粗暴的做法。
public class InvokeByRuntime {
/**
* @param args
* @throws IOException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException {
String exe = "python";
String command = "D:\\calculator_simple.py";
String num1 = "1";
String num2 = "2";
String[] cmdArr = new String[] {exe, command, num1, num2};
Process process = Runtime.getRuntime().exec(cmdArr);
InputStream is = process.getInputStream();
DataInputStream dis = new DataInputStream(is);
String str = dis.readLine();
process.waitFor();
System.out.println(str);
}
}
输出:
3
calculator_simple.py:
# coding=utf-8
from sys import argv
num1 = argv[1]
num2 = argv[2]
sum = int(num1) + int(num2)
print sum
显然,在Java中通过Runtime调用Python程序与直接执行Python程序的效果是一样的,可以在Python中读取传递的参数,也可以在Java中读取到Python的执行结果。需要注意的是,不能在Python中通过return语句返回结果,只能将返回值写入到标准输出流中,然后在Java中通过标准输入流读取Python的输出值。
通过Jython调用
通过Jython调用Python?我在听到这个概念的时候一脸懵逼,不是说好的在Java中调用Python程序吗?这个Jython是什么鬼?难道是一个在Java中调用Python程序的组件或工具?其实,关于Jython是什么这个疑问,我估计有许多人在一开始接触的时候也是很疑惑的,下面我们就一一道来。
1. 什么是Jython
Jython主页:http://www.jython.org/currentdocs.html
按照官方的定义,Jython是Python语言在Java平台的实现。这个概念似乎有点拗口,反正我一开始并没有理解。Python难道不已经是一门语言了吗?什么叫做Jython是Python语言在Java平台的实现?
实际上,之所以存在这样的困惑主要是因为我们对Python语言的相关概念掌握和理解不清楚导致的。
Python其实只是一个语言规范,它存在多个不同语言实现的版本。具体来说,目前Python语言存在如下几个具体实现:
(1)CPython:CPython是标准Python,也是其他Python编译器的参考实现。通常提到“Python”一词,都是指CPython。CPython由C编写,将Python源码编译成CPython字节码,由虚拟机解释执行。没有用到JIT等技术,垃圾回收方面采用的是引用计数。
(2)Jython:Jython是在JVM上实现的Python,由Java编写。Jython将Python源码编译成JVM字节码,由JVM执行对应的字节码。因此能很好的与JVM集成,比如利用JVM的垃圾回收和JIT,直接导入并调用JVM上其他语言编写的库和函数。
(3)IronPython:IronPython与Jython类似,所不同的是IronPython在CLR上实现的Python,即面向.NET平台,由C#编写。IronPython将源码编译成TODO CLR,同样能很好的与.NET平台集成。即与Jython相同,可以利用.NET框架的JIT、垃圾回收等功能,能导入并调用.NET上其他语言编写的库和函数。IronPython默认使用Unicode字符串。
(4)PyPy:这里说的PyPy是指使用RPython实现,利用Tracing JIT技术实现的Python,而不是RPython工具链。PyPy可以选择多种垃圾回收方式,如标记清除、标记压缩、分代等。
(5)Pyston:Pyston由Dropbox开发,使用C++11编写,采用Method-at-a-time-JIT和Mark Sweep——Stop the