C:\jpython>jpython >>> from java.util import Random >>> r = Random() >>> r.nextInt() -790940041 >>> for i in range(5): ... print r.nextDouble() ... 0.23347681506123852 0.8526595592189546 0.3647833839988137 0.3384865260567278 0.5514469740469587 >>>
In order to use a Java package under JPython, you must make JPython aware of the package. This can be done in one of two ways. You can modify the JPython registry entry to include the package under the "java.packages" key (see the previous section for more details on this). Or you can call the function "sys.add_package(package_name)" at runtime to make JPython aware of any arbitrary package. The previous example assumed that JPython was aware of the "java.util" package (which it is by default). If it wasn't aware of this package, a new line would need to be added to the top of the example which read, "import sys; sys.add_package('java.util')"
Java methods and functions are called just exactly like their Python
counterparts. There is some automatic type coercion that goes on
both for the types being passed in and for the value returned by the method.
The following table shows how Python objects are coerced to Java objects
when passed as arguments in a function call. The Java Types show the expected
java type for the argument, and the Allowed Python Types shows what Python
objects can be converted to the given Java type. Notice the special
behavior of String's when a java.lang.Object is expected. This behavior
might change if I am shown that it causes problems.
Java Types | Allowed Python Types |
---|---|
char | String (must have length 1) |
boolean | Integer (true = nonzero) |
byte, short, int, long | Integer or Float |
float, double | Float |
java.lang.String, byte[] | String |
java.lang.Class | Class or JavaClass (only if class subclasses from exactly one Java class) |
Foo[] | Array (must contain objects of class or subclass of Foo) |
java.lang.Object | String->java.lang.String, all others unchanged |
org.python.core.PyObject | All unchanged |
Foo | Instance->Foo (if Instance is subclass of Foo);
JavaInstance -> Foo (if JavaInstance is instance of Foo or subclass) |
Java Type | Returned Python Type |
---|---|
char | String (of length 1) |
boolean | Integer (true = 1, false = 0) |
byte, short, int, long | Integer |
float, double | Float |
java.lang.String | String |
java.lang.Class | JavaClass which represents given Java Class |
Foo[] | Array (containing objects of class or subclass of Foo) |
org.python.core.PyObject (or subclass) | Unchanged |
Foo | JavaInstance which represents the Java Class Foo |
When the difference is instead in the types of the arguments, more work is required. The possible signatures are sorted in a consistent order that should ensure the appropriate method is chosen first. More information on exactly how this sorting is performed will be provided when I have the time.
If you need to call a Java method with a particular signature and this is not happening in the easy way, you can use the following workaround:
Assume that foo has two methods, "void foo(int x); void foo(byte x);". To call the second method you could write the following:
from java.lang import Byte
foo(Byte(10))I'm not convinced that any better solution to this problem is possible.
i.e. You can't type in Python "foo.print('hello')" to call some Java objects "print" method. However, you can do the following, "getattr(foo, 'print')('hello')".