在从Java传递对象到Jython时保留Java类型
我想知道有没有办法让 jython 不自动把 Java 对象变成 Python 类型,特别是当你把它们放进 Java 的 ArrayList 里时。
这是我在 jython 控制台上复制的一个例子:
>>> b = java.lang.Boolean("True");
>>> type(b)
<type 'javainstance'>
>>> isinstance(b, java.lang.Boolean);
1
到目前为止,一切都很好,但如果我把对象放进一个 ArrayList 里
>>> l = java.util.ArrayList();
>>> l.add(b)
1
>>> type(l.get(0))
<type 'int'>
这个对象就会变成一个类似 Python 的布尔值(也就是一个整数),然后…
>>> isinstance(l.get(0), java.lang.Boolean)
0
这就意味着我再也看不到它曾经是 java.lang.Boolean 了。
澄清一下
我想要的其实是避免在把对象从 Java 传到 Python 时,自动转换 Java 类型为 Python 类型。我再举一个例子来说明。
一个 Python 模块:
import java
import IPythonModule
class PythonModule(IPythonModule):
def method(self, data):
print type(data);
还有一个使用这个模块的 Java 类:
import java.util.ArrayList;
import org.python.core.PyList;
import org.testng.annotations.*;
import static org.testng.AssertJUnit.*;
public class Test1 {
IPythonModule m;
@BeforeClass
public void setUp() {
JythonFactory jf = JythonFactory.getInstance();
m = (IPythonModule) jf.getJythonObject(
"IPythonModule",
"/Users/sg/workspace/JythonTests/src/PythonModule.py");
}
@Test
public void testFirst() {
m.method(new Boolean("true"));
}
}
在这里,我会看到输出是 'bool',这是因为发生了隐式转换,但我真正想看到的是 'javainstance' 或 'java.lang.Boolean'。如果你想运行这段代码,你还需要 JythonFactory 类,可以在 这里 找到。
1 个回答
你似乎在使用一个旧版本的Jython。在现在的Jython版本中,Python里的 bool
类型对应的是Java里的 Boolean
。
Jython在把数据放进 ArrayList
的时候,并不会把Java类型转换成Python类型。相反,当你把一个原始的Python类型传给Java方法时,它会把这个Python类型转换成原始的或包装的Java类型,而当数据从Java出来时,它才会把Java类型转换成Python类型。
你可以通过打印数组的内容来观察这一点。注意,Python的 bool
是大写的(True
),而Java的 Boolean
不是。
>>> from java.lang import Boolean
>>> b = Boolean('True')
>>> b
true
>>> from java.util import ArrayList
>>> l = ArrayList()
>>> l.add(b)
True
>>> l
[true]
>>> l.add(True)
True
>>> l
[true, true]
>>> list(l)
[True, True]
如果这样还是不能满足你的需求,可以考虑写一个小的Java辅助函数,直接检查数组而不进行转换。可以说,Jython没有自动把你构造的 Boolean
转换成Python的 bool
是个bug,这样一来,你使用 Boolean.TRUE
或Python的 True
并没有什么优势。