python类型转换java类型

  • 本章概述
  • 参数类型转换参考表
  • 示例
    • byte
    • short
    • int
    • long
    • float
    • double
    • boolean
    • char
    • String
    • Array
      • int[]
      • String[]
      • 自定义对象数组
    • 自定义Class对象
    • List
    • Map
    • Enum
  • 总结
  • 示例源码:

本章概述

python调用java,关键的一点是python 类型和 Java 类型之间的转换。这个功能借助JPype完成,Jpype提供了一系列API,帮助使用者完成python参数到java参数的转换。
本章的目的是尽可能覆盖java参数类型,通过示例演示如何将python数据类型转换为指定的java数据类型。

参数类型转换参考表

这部分原文链接如下:
http://jpype.sourceforge.net/doc/user-guide/userguide.html#conversion

下图横坐标代表java类型,竖坐标代表python类型,其中以“J”开头的,是JPype封装的类型,由于JPype是python的一个模块,所以Jpype封装的类型在这里也认为是python类型。

JPype 定义了 Python 对象和 Java 类型之间“匹配”的不同层次。这些级别是:

  • 下图空白单元格:代表对应的两个类型没有办法转换。
  • 单元格为“I”的:JPype 将根据需要进行转换,即隐式转换。
  • 单元格为“X”的:与“I”对应,是显示转换,但优先级高于隐式转换。比如有的类型同时支持隐式转换和显示转换,如果明确指定显示转换,则转换过程就是显示转换。举个例子,java的byte类型,对应到python中int、long、JByte类型都可以转换为byte类型。如果一个java函数的参数是byte类型,那么在python中调用这个java函数时,参数值可以直接填写python中的数字(python2才区分Long类型, python3统一划分为数字类型),这时是把参数自动隐式转换java的byte类型。参数值也可以填JByte(2)这样的显示转换,这时是把参数值显示转换给java中的byte类型,此时隐式转换是不生效的。


对于上图单元格中的数字,是对该单元格所对应的转换关系的补充说明:
(1) 如果 Python 值适合 java 本机类型,则会发生转换。

(2) 如果python字符串或unicode长度为1,则发生转换

(3) 所需对象的类型必须与java.lang.String ( java.lang.Object , java.util.Comparable )兼容

(4) 维数必须匹配,类型必须兼容

(5) 仅当需要的类型为java.lang.Object 时

(6) 仅当 JObject 包装器的指定类型是兼容的数组类时。

(7) 仅当所需的类型与包装器的指定类型兼容时。不考虑 java 对象的实际类型。

(8) 仅当requireds 类型与Java Object 实际类型兼容时。

(9) 仅当所需类型为java.lang.Object或java.lang.Class 时

(10) 只有 True 和 False 值被隐式转换为布尔值。

示例

下面通过示例演示python类型与java类型的转换,笔者为了使转换过程看起来更规范,都是使用显示转换。这样所有的转换统一依赖Jpype提供的API来完成。

byte

java :

package com.linchao;public class myJpypeTest {public int test_byte(byte param){int res =  param + 1;return res;}public static void main(String[] args){System.out.println("Jpype Test...");}
}

python:

# coding: utf-8
# TransferParam。py
from jpype import JBytedef to_byte(param):return JByte(param)
# coding: utf-8from jpype import JClass
import jpype
from TransferParam import to_byteif __name__ == "__main__":jpype.startJVM(classpath=r"D:\myProjects\java\JpypeTest\out\artifacts\JpypeTest_v0_1\JpypeTest_v0.1.jar")myJpypeTest = JClass("com.linchao.myJpypeTest")()# 测试byte类型转换res = myJpypeTest.test_byte(to_byte(100))print(res)

输出结果

"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
101Process finished with exit code 0

第一个示例,显示了java和python的全部代码。
后面的示例,为了更清晰的排版和显示主要内容,只贴关键代码。不过完整的代码可以到指定链接获取。

short

java:

public String test_short(short param){int res = param + 1;return param + "+" + "1" + "=" + res;}

python:

def to_short(param):return JShort(param)
# 测试short类型转换
res = myJpypeTest.test_short(to_short(100))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
100+1=101Process finished with exit code 0

int

java:

    public String test_int(int param){int res = param + 1;return param + "+" + "1" + "=" + res;}

python:

def to_int(param):return JInt(param)
# 测试int类型转换
res = myJpypeTest.test_int(to_int(200))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
200+1=201Process finished with exit code 0

long

java:

    public String test_long(long param){long res = param + 1;return param + "+" + "1" + "=" + res;}

python:

def to_long(param):return JLong(param)
# 测试long类型转换
res = myJpypeTest.test_long(to_long(300))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
300+1=301Process finished with exit code 0

float

java:

    public String test_float(float param){float res = param + 1;return param + "+" + "1" + "=" + res;}

python:

def to_float(param):return JFloat(param)
# 测试float类型转换
res = myJpypeTest.test_float(to_float(400.54))
print(res)
"D:\Program Files\Python39\python.exe" "D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
400.54+1=401.54Process finished with exit code 0

double

java:

    public String test_double(double param){double res = param + 1;return param + "+" + "1" + "=" + res;}

python:

def to_double(param):return JDouble(param)
# 测试double类型转换
res = myJpypeTest.test_double(to_double(520.54))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
520.54+1=521.54Process finished with exit code 0

boolean

java:

    public String test_boolean(boolean param){if(param == true){return "param is true"; }else {return "param is false";}}

python:

def to_boolean(param):return JBoolean(param)
# 测试boolean类型转换
res = myJpypeTest.test_boolean(to_boolean(False))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
param is falseProcess finished with exit code 0
# 测试boolean类型转换
res = myJpypeTest.test_boolean(to_boolean(True))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
param is trueProcess finished with exit code 0

char

java:

    public String test_char(char param){int a = param;return "ascii: " + param + "->" + a;}

python:

def to_char(param):return JChar(param)
# 测试char类型转换
res = myJpypeTest.test_char(to_char("a"))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
ascii: a->97Process finished with exit code 0

String

java:

    public String test_String(String param){return "Hello! " + param ;}

python:

def to_String(param):return JString(param)
# 测试String类型转换
res = myJpypeTest.test_String(to_String("Devin"))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
Hello! DevinProcess finished with exit code 0

Array

在java中,数组类型根据数组元素,可以是整形数组、字符串数组、某种对象的数组等等。但无论是什么类型的数组,在jpype中,都是通过JArray这个API来实现。
示例

int[]: JArray(JInt)
float[]: JArray(JFloat)
String[]: JArray(JString)

JArray API返回一个JClass对象,通过传入参数调用这个对象即可以得到一个数组对象。调用这个对象有两种传参方式,第一种是传入一个整数,会得到一个长度为整数的数组,数组中的元素值默认初始化值(int是0,String是None),第二种方式是传入序列,得到一个长度为序列长度,元素值为序列值的数组。
看代码演示:

int[]

java:

    public int test_Array(int[] param){int sum = 0;for(int i : param){sum = sum + i;}return sum;}

python:

def to_int_array(param):return JArray(JInt)(param)
# 测试int[]类型转换
# 传入的数组是[0,0,0,0,0]
res = myJpypeTest.test_Array(to_int_array(5))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
0Process finished with exit code 0
# 传入的数组是[1,2,3,4,5]
res = myJpypeTest.test_Array(to_int_array([1,2,3,4,5]))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
15Process finished with exit code 0

String[]

Java:

    public String test_Array(String[] param){String sum = "";for(String i : param){sum = sum + i;}return sum;}

python:

def to_String_array(param):return JArray(JString)(param)
# 测试String[]类型转换
res = myJpypeTest.test_Array(to_String_array(["我", "爱", "中", "国"]))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
我爱中国Process finished with exit code 0

自定义对象数组

这个例子是在java中自定义对象,然后定义一个函数,其输入参数是自定义对象。最后在python中调用这个函数。
首先,看看在java中自定义的对象,这是一个描述动物的对象,有名字、年龄、别名三个私有属性,对外提供了一个接口返回一段自我介绍。

package params;public class Animals {private String name="";private int age=0;private String alias="";public Animals(String name, int age, String alias) {this.name = name;this.age = age;this.alias = alias;}public String sayHello(){return "你好!我是" + this.name + ",今年" + this.age + "岁, 人们通常叫我"+ this.alias;}
}

java中待调用的目标函数:

//  遍历Animals数组,调用每个动物的sayHello接口,将其自我介绍打包到一个序列里并返回。public List<String> test_Array(Animals[] params){List<String> res = new ArrayList();for(Animals animal: params){res.add(animal.sayHello());}return res;}

接下来是python中,自定义对象数组的转换:

def to_Animal_array(param, Animal):return JArray(Animal)(param)
# 测试自定义对象数组类型转换
names = ["假老练", "风车车", "莽哥"]
ages = [3,2,4]
alias = ["猫儿", "耗子", "狗儿"]
# 得到Animals类定义
Animal = JClass("params.Animals")
animals = []
for i in range(3):# 初始化Animal,并将其加入到列表里。animals.append(Animal(to_String(names[i]), to_int(ages[i]), to_String(alias[i])))
# 参数准备工作已经完成,调用java函数。
res = myJpypeTest.test_Array(to_Animal_array(animals, Animal))
for i in res:print(i)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
你好!我是假老练,今年3岁, 人们通常叫我猫儿
你好!我是风车车,今年2岁, 人们通常叫我耗子
你好!我是莽哥,今年4岁, 人们通常叫我狗儿Process finished with exit code 0

这是一个较为综合性的示例,还涉及到了下面才要描述的自定义对象类型转换。如果这里暂时没看懂,没关系,先看下面,然后再回过头来看这个示例。

自定义Class对象

依然使用Animals对象:

package params;public class Animals {private String name="";private int age=0;private String alias="";public Animals(String name, int age, String alias) {this.name = name;this.age = age;this.alias = alias;}public String sayHello(){return "你好!我是" + this.name + ",今年" + this.age + "岁, 人们通常叫我"+ this.alias;}
}
    public String test_class(Animals animals){return animals.sayHello();}

在python中调用这个函数:

# Animal类构造函数接受三个参数,但param是个序列,所以用了*
def to_java_class(cls, param):# 获得java classjava_class = JClass(cls)# 调用java class的构造函数示例化对象return java_class(*param)
# 测试自定义类型转换
res = myJpypeTest.test_class(to_java_class("params.Animals", [to_String("假老练"), to_int(3), to_String("猫儿")]))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
你好!我是假老练,今年3岁, 人们通常叫我猫儿Process finished with exit code 0

Tips:

python中的 JClass("params.Animals")
类似java中的 import params.Animals;

List

对于java中List类型对象,jpype使用java.util.ArrayList这个api来转换。
List<String>为例:
Java:

    public String test_List(List<String> params){String res = "";for(String param : params){res = res + param;}return res;}

python:

def to_list(param):return java.util.ArrayList(param)
# 测试自定义类型转换
res = myJpypeTest.test_List(to_list(["新","年","快","乐"]))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
新年快乐Process finished with exit code 0

Map

java中的Map下常见的是HashMap和LinkedHashMap。
分别对应jpype的java.util.HashMap、java.util.LinkedHashMap两个API。使用方法是相似的。
以HashMap为例子。
java:

     public String test_Map(HashMap<String, Integer> params){int age = params.get("age");int rmb = params.get("RMB");return "age:"+age+" rmb:"+rmb;}

python:

def to_HashMap(param):return java.util.HashMap(param)
# 测试自HashMap类型转换
res = myJpypeTest.test_Map(to_HashMap({to_String("age"):to_int(18), to_String("RMB"):to_int(999999)}))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
age:18 rmb:999999Process finished with exit code 0

Enum

java:

package params;public enum testEnum {RED("红色"), GREEN("绿色"), BLANK("白色"), YELLO("黄色");private String color;testEnum(String color) {this.color = color;}public String getColor() {return color;}
}
    public String test_Enum(testEnum testenum){return testenum.getColor();}

python:

def to_Enum(cls, param):# 获得枚举类java_class = JClass(cls)# 获取枚举对象中的成员return getattr(java_class, param)
# 测试自Enum类型转换
res = myJpypeTest.test_Enum(to_Enum("params.testEnum", "RED"))
print(res)
"D:\Program Files\Python39\python.exe" D:/myProjects/python/test_JPype/main.py
红色Process finished with exit code 0

总结

本文描述如何通过jpype完成python类型到java类型的转换。
包含了java原生类型,以及自定义对象类型、数组类型、枚举类型、List类型、Map类型。

示例源码:

https://github.com/linchao001/testJpype

python调用java之jpype参数类型转换相关推荐

  1. python调用java之Jpype实现java接口

    python实现java接口 概述 java程序 java接口 java测试函数 在python中实现java接口的两种方式 第一种:JImplements JImplements的使用示例 JImp ...

  2. Python调用Java代码部署及初步使用

    Python调用Java代码部署: jpype下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#jpype 下载的时候需要使用Chrome浏览器进行下载 ...

  3. 绿化版Java11的环境配置与Python调用Java

    绿化Java环境的安装与配置 安装JDK 在Oracle的官网下载: 官方最新版本是16,个人选择下载11版本的zip压缩包:jdk-11.0.6_windows-x64_bin.zip 网盘下载地址 ...

  4. python调用java代码方法

    前言: 公司要测试对外接口,接口中的数据又涉及到加密的问题,而python对加密数据进行位运算后,居然无法逆向位运算回来了(应该是个人能力不够吧),只好调用同事之前用的java代码中的函数去解码了,花 ...

  5. python调用java方法_python调用java

    一.环境确认: 首先,要确认安装的jdk版本是1.8以上:其次,jdk安装位数与python安装的位数一致,及要么一起64位版本要么一起32版本. (以上2点不满足均会报错,比如:not found ...

  6. python调用java的方法

    最近自己开发的一套测试平台,因为上游系统经常修改主数据,导致其中一个功能经常失败,要频繁找上游测试帮忙修改数据. 基于此种原因,对于这种过于依赖上游系统的接口,决定放弃直接调上游系统的http请求下发 ...

  7. python调用java文件_Python程序中调用Java代码的实践

    1.环境准备 windows 7(64位)+JDK(64位)+Python(64位)+eclipse+pycharm 还需要一个作为桥梁的工具包,jpype1,这个工具包可以启动jvm,使java代码 ...

  8. Python 调用Java

    2019独角兽企业重金招聘Python工程师标准>>> 前提: Linux 环境 1 安装 jpype1 安装后测试代码: from jpype import * startJVM( ...

  9. 【Groovy】Groovy 方法调用 ( Java 中函数参数是接口类型 | 函数参数是接口类型 可以 直接传递闭包 )

    文章目录 一.Java 中函数参数是接口类型 二.函数参数是接口类型 可以 直接传递闭包 三.完整代码示例 一.Java 中函数参数是接口类型 在 Android 中经常使用如下形式的接口 : 定义一 ...

  10. python调用java的jar包_python调用java的jar包报错127

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 最近在弄python需要调用到Java的jar包,按照网上的教程走,最后总是报错No matching overloads found for [init ...

最新文章

  1. vue中通过数据双向绑定给video标签的src赋值,只有第一次有效,怎么解决?
  2. 通过scatter图寻找噪音
  3. spring mvc import resource路径问题【最简单的却也是最致命的】
  4. java中的基本数据类型_Java中的基本数据类型和引用数据类型
  5. 4线电子围栏安装示意图_电子围栏报警系统安装施工过程(图解)
  6. 说明exit()函数作用的程序
  7. NVIDIA PhysX宣布正式开源 最强物理仿真引擎
  8. 数据库系统由计算机硬件软件,集美大学计算机工程学院数据库软件04B卷答案.doc...
  9. JAVA计算一年的第几天问题
  10. chrome 下载东西 失败禁止_如何修复最常见的Google Chrome下载错误
  11. CISSP考试复习经历分享2020年12月
  12. Emu8086下载和注册
  13. kdj买卖指标公式源码_长短KDJ源码与kdj顶底背离指标公式(附图)
  14. linux格式化u盘为ntfs格式,Linux上格式化U盘为NTFS格式
  15. LSL-- Flow Control
  16. Linux下的LVM逻辑卷管理
  17. android 获取视频长度,android中如何获取视频时长
  18. 云生态瞭望 | 腾讯云生态暖伙伴心
  19. ai人工智能测面相 准吗_金融界的AI:如何最终开始相信自己的回测[1/3]
  20. SpringBoot中405异常

热门文章

  1. 威纶通触摸屏与仪表通讯_详解通信威纶通触摸屏与英威腾变频器的使用
  2. 高性能的java的ip资源扫描和端口分析
  3. 一款免费且强大的gif动画录制工具,再也不愁录动画!
  4. IDEA字体设置详解
  5. 小工具-悬浮窗LogViewer在android手机上查看数据日志
  6. 有了HTML5,Flash还能走多远
  7. 红米note5linux刷机包__最新最全的红米Note5ROM刷机包下载、刷机教程_红米Note5论坛_移动叔叔...
  8. Python爬取豆瓣网图书评论
  9. Matlab Coder将m文件转换成C/C++
  10. 《The Pragmatic Programer》 reading notes