- Jython code can be compiled & compressed as a “.jar” file indeed.
- But we also have to consider how a Java code would see & use a Jython class.
- In Java all classes implicitly inherits from class Object:
- Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html
- But in Jython, if we don’t specify, a class doesn’t inherit from any class by default.
- From now on, everything I say is pure speculation, b/c I’ve never seen a Jython coded library yet.
- So in order to be on the safer side, any exposed class should inherit from an already existing Java class or in the very least from the Object class.
- That is, the 1 w/ capital “O”, not Jython’s object w/ lowercase “o”:
from java.lang import Object
class JythonClass(Object): pass
- AFAIK, everything in Jython is a PyObject:
PyObject (Jython API documentation) - Therefore anything we return from a Jython method is gonna be by default a PyObject derived datatype.
- That surely wouldn’t be very practical for some1 using such a Jython class from within their Java code.
- So this Jython class below:
from java.lang import Object
class JythonClass(Object):
def __init__(self, someValue): self.val = someValue
def intAdd(self, someValue):
self.val += someValue
return self.val
def floatAdd(self, someValue):
self.val += someValue
return self.val * 1.0
def strAdd(self, someValue):
self.val += someValue
return `self.val`
def listAdd(self, someValue):
self.val += someValue
return [self.val]
def toString(self): return `self.val`
- I believe it would probably become something like this when accessed from the Java side:
import org.python.core.*;
public static class JythonClass {
public int val;
public JythonClass(int someValue) {
val = someValue;
}
PyInteger intAdd(int someValue) {
val += someValue;
return new PyInteger(val);
}
PyFloat floatAdd(int someValue) {
val += someValue;
return new PyFloat(val);
}
PyString strAdd(int someValue) {
val += someValue;
return new PyString(str(val));
}
PyList listAdd(int someValue) {
val += someValue;
PyList pl = new PyList();
pl.append(new PyInteger(val));
return pl;
}
- That would demand more effort for the Java programmer to convert the returned datatype to another 1 more familiar:
int intVal = jython.intAdd(50).asInt(); // explicit conversion method call
- The method above intAdd() would probably return datatype PyInteger, not a Java primitive
int
:
PyInteger (Jython API documentation) - So a Java programmer would need to know that a call to asInt() is necessary in order to store method intAdd()'s returned value to a Java
int
variable:
PyInteger (Jython API documentation) - As a workaround we can convert a Jython datatype to a more common Java 1 before returning a value from a method:
from java.lang import Object, Integer, Float, String
from java.util import ArrayList
class JythonClassWorkaround(Object):
def __init__(self, someValue): self.val = someValue
def IntegerAdd(self, someValue):
self.val += someValue
return Integer(self.val)
def FloatAdd(self, someValue):
self.val += someValue
return Float(self.val)
def StringAdd(self, someValue):
self.val += someValue
return String(`self.val`)
def ArrayListAdd(self, someValue):
self.val += someValue
return ArrayList([self.val])
def toString(self): return String(`self.val`)
- The class JythonClassWorkaround above would be much easier for a Java programmer IMO.
- Probably it would be seen as something like this in Java:
import org.python.core.*;
public static class JythonClassWorkaround {
public int val;
public JythonClassWorkaround(int someValue) {
val = someValue;
}
Integer IntegerAdd(int someValue) {
val += someValue;
return new Integer(val);
}
Float FloatAdd(int someValue) {
val += someValue;
return new Float(val);
}
String StringAdd(int someValue) {
val += someValue;
return new String(str(val));
}
ArrayList<Integer> ArrayListAdd(int someValue) {
val += someValue;
ArrayList<Integer> al = new ArrayList<Integer>(1);
al.add(new Integer(val));
return al;
}
String toString() {
return new String(str(val));
}
}
- Here’s a Java test-drive for both classes:
import org.python.core.*;
JythonClass jython = new JythonClass(100);
JythonClassWorkaround jyJava = new JythonClassWorkaround(100);
int intVal;
float floatVal;
String strVal;
ArrayList<Integer> listVal;
void setup() {
println(jython, jyJava); // 100 100
intVal = jython.intAdd(50).asInt(); // explicit conversion method call
println(intVal); // 150
intVal = jyJava.IntegerAdd(-70); // auto-unboxing
println(intVal); // 30
floatVal = (float) jython.floatAdd(-30).asDouble(); // conversion method
println(floatVal); // 120.0
floatVal = jyJava.FloatAdd(20); // auto-unboxing
println(floatVal); // 50.0
strVal = jython.strAdd(-45).toString(); // explicit conversion method call
println(strVal); // 75
strVal = jyJava.StringAdd(10); // already a Java string
println(strVal); // 60
listVal = new ArrayList<Integer>(jython.listAdd(-35));
println(listVal); // [40]
listVal = jyJava.ArrayListAdd(23);
println(listVal); // [83]
exit();
}
P.S.: Jython’s javadoc: jython 2.7.3 javadoc (org.python)