Getting the Class Object and name of a Java Class and Interface in Jython

Monday, February 9, 2009

In my last post, we have seen how to get the Class Object and name of a java class and interface from java, in this post, we will see how to get the Class Object and name of a java class and interface from jython, for those of you who are new to jython, its an implementation of Python programming language on JVM, from jython, in addition to standard python libraries, you can also access java class libraries, create instances and invoke their methods.

I have been blogging about jython for quite some time and its become my habit to explore the equivalent jython script of any java code I write and that infact has thrown some surprises, its not a straightforward conversion at times and there are subtle differences in the way jython and java works, but if you are a java programmer who want to explore jython, there is no need to panic as jython follows java rules, so whatever java concepts you have learned is applicable for jython (to comply to java in itself is a great design challenge for jython developers).

Lets come back to the topic on how to get the Class Object and name of a java class and interface from jython, see the below code and its explanation.

Listing 1: ClassName.py
1.  ##
2. ##ClassName.py
3. ##Author: S.Prasanna
4. ##
5.
6. from javax.swing.text.html import HTML
7. from java.lang.management import RuntimeMXBean
8. from java.lang import Class
9.
10. ##Getting the Class Object and name of a java class
11.
12. htmlObj = HTML()
13. print "HTML Class Object using getClass method =", htmlObj.getClass()
14. print "HTML Class Object using Class.forName =", Class.forName("javax.swing.text.html.HTML")
15. print "HTML Class Object name using getName method=", htmlObj.getClass().getName()
16.
17. ##Getting the Class Object and name of a java interface
18.
19. print """RuntimeMXBean Class Object using RuntimeMXBean.class =""", RuntimeMXBean.class
20. ##Returns java.lang.Class, not the right Class object of RuntimeMXBean, it
21. ##should be java.lang.management.RuntimeMXBean, whereas RuntimeMXBean.class
22. ##in java would return java.lang.management.RuntimeMXBean
23.
24. print "RuntimeMXBean Class Object using Class.forName =", Class.forName("java.lang.management.RuntimeMXBean")
25. print "RuntimeMXBean Class Object name using getName method =" , Class.getName(Class.forName("java.lang.management.RuntimeMXBean"))
26. ##This would return java.lang.management.RuntimeMXBean since
27. ##java.lang.management.RuntimeMXBean is a valid interface, therefore in
28. ##jython to get a Class object of an interface, use Class.forName and the
29. ##full qualified package and interface name as an argument
30.
Output:

C:\jython>jython ClassName.py
HTML Class Object using getClass method = javax.swing.text.html.HTML
HTML Class Object using Class.forName = javax.swing.text.html.HTML
HTML Class Object name using getName method= javax.swing.text.html.HTML
RuntimeMXBean Class Object using RuntimeMXBean.class = java.lang.Class
RuntimeMXBean Class Object using Class.forName = java.lang.management.RuntimeMXBean
RuntimeMXBean Class Object name using getName method = java.lang.management.RuntimeMXBean

Explanation:

We are importing a java class (line 6, javax.swing.text.html.HTML) and an interface (line 7, java.lang.management.RuntimeMXBean) for which we are going to get the Class Object and its name. For regular java classes, getting the Class Object and its name works similar in java as well as jython, either you can use getClass method (line 13) or Class.forName method with the fully qualified package and class name as argument (line 14) and the getName method of the Class object returns the name of the class (line 15).

For java interfaces, the output is little different in jython compared to java, in java you can use the .class attribute of the interface to get the java interface's Class Object, in jython even though you can use the .class attribute for a java interface, but it doesn't return the exact Class object name of that java interface (line 19, where RuntimeMXBean.class returns java.lang.Class and not java.lang.management.RuntimeMXBean, but RuntimeMXBean.class in java would return "interface java.lang.management.RuntimeMXBean", see here).

Therefore to get the Class Object of a java interface using jython, you should only use Class.forName method with the fully qualified package and interface name as an argument (line 24) as the .class attribute of the java interface may not work correctly in jython (also note that the .class attribute can only be used in jython and its not valid in CPython, but class is a keyword in both CPython as well as JPython), then to get the Class Object name of a java interface in jython, you can invoke the getName method of the Class object you got through Class.forName (line 25, its redundant though as Class.getName(Class.forName("java.lang.management.RuntimeMXBean")) would return "java.lang.management.RuntimeMXBean" ). The moral, there is always a difference between jython and java.

1 comment:

ProjectMoon said...

In the latest version of Jython (2.5.1), you can actually retrieve the Class object from a Java class without instantiating it by referring to the class's name itself:

from java.util import ArrayList
print ArrayList.name

^ArrayList.name is equivalent to ArrayList.class.getName() in Java.


Copyright © 2008 Prasanna Seshadri, www.prasannatech.net, All Rights Reserved.
No part of the content or this site may be reproduced without prior written permission of the author.