Java Objects in Matlab
Contents
What are Java Class Objects?
Think of Class objects as blueprint for creating instances. Another way to think of objects of type Class is as a meta-object. That is, class objects contain metadata information about an object such as
- name
- methods
- constructors
- annotations
and other various helper functions such as isInterface() and isAbstract() etc.
Typically, Class objects can be obtained by asking an instance for it's Class like this:
% create an instance of an ArrayList list = java.util.ArrayList(); % ask the ArrayList instance for its Class arrayListClass = list.getClass()
arrayListClass = class java.util.ArrayList
Using the Class object we can make queries about the ArrayList object such
% what is the name of the package which contains ArrayList pkg = arrayListClass.getPackage() % figure out what methods the instance responds to arrayListMethods = arrayListClass.getMethods()
pkg = package java.util, Java Platform API Specification, version 1.7 arrayListMethods = java.lang.reflect.Method[]: [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method] [java.lang.reflect.Method]
And for the purposes of building proxy objects, we are particularly interested in interfaces
% figure out if the class implements any interfaces
interfaces = arrayListClass.getInterfaces()
interfaces = java.lang.Class[]: [java.lang.Class] [java.lang.Class] [java.lang.Class] [java.lang.Class]
Notice that when asking for interfaces we get back an array of Class objects, one for each interface implemented. These Class objects will allow us to make queries about interfaces implmented. For example
% print the names of each interface implemented by ArrayList
arrayfun(@(i)disp(i.getName()),interfaces)
java.util.List java.util.RandomAccess java.lang.Cloneable java.io.Serializable
Similarly, it is straight forward to obtain the method signatures for all methods of ArrayList
% print out function signatures for all methods of ArrayList
arrayfun(@(m)disp(char(m.toGenericString())),arrayListMethods)
public void java.util.ArrayList.add(int,E) public boolean java.util.ArrayList.add(E) public E java.util.ArrayList.remove(int) public boolean java.util.ArrayList.remove(java.lang.Object) public E java.util.ArrayList.get(int) public java.lang.Object java.util.ArrayList.clone() public int java.util.ArrayList.indexOf(java.lang.Object) public void java.util.ArrayList.clear() public boolean java.util.ArrayList.isEmpty() public int java.util.ArrayList.lastIndexOf(java.lang.Object) public boolean java.util.ArrayList.contains(java.lang.Object) public int java.util.ArrayList.size() public java.util.List<E> java.util.ArrayList.subList(int,int) public java.lang.Object[] java.util.ArrayList.toArray() public <T> T[] java.util.ArrayList.toArray(T[]) public boolean java.util.ArrayList.addAll(java.util.Collection<? extends E>) public boolean java.util.ArrayList.addAll(int,java.util.Collection<? extends E>) public java.util.Iterator<E> java.util.ArrayList.iterator() public E java.util.ArrayList.set(int,E) public void java.util.ArrayList.ensureCapacity(int) public void java.util.ArrayList.trimToSize() public boolean java.util.ArrayList.removeAll(java.util.Collection<?>) public boolean java.util.ArrayList.retainAll(java.util.Collection<?>) public java.util.ListIterator<E> java.util.ArrayList.listIterator(int) public java.util.ListIterator<E> java.util.ArrayList.listIterator() public boolean java.util.AbstractList.equals(java.lang.Object) public int java.util.AbstractList.hashCode() public java.lang.String java.util.AbstractCollection.toString() public boolean java.util.AbstractCollection.containsAll(java.util.Collection<?>) public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public final native java.lang.Class<?> java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll()
Finally, to actually instaciate an ArrayList instance (i.e. an actual ArrayList rather than metadata about an ArrayList) we can as the Class object to create one for us
% create instance of ArrayList using it's Class object
arrayList = arrayListClass.newInstance()
arrayList = []
Authenticity can be verified using built-in Matlab function isa
% confirm arrayList is actually of type java.util.ArrayList isa(arrayList,'java.util.ArrayList')
ans = 1
and likewise, the verification in a very round about fashion which emphisizes use of the associated Class object
strcmp('java.util.ArrayList',arrayList.getClass().getName())
ans = 1
Loading Java Classes in Matlab
The first step in building a Java proxy is to load the Class blueprint. Classes in Java can be listed on the static class path (loaded at launch) or the dynamic class path (loaded at runtime) However, loading Java Classes on the dynamic classpath in Matlab can be a little fickle.
If the class to load is listed on Matlab's static class path ($matlabroot/toolbox/local/classpath.txt) then the simplest way to proceed is
% load class object for Java EventLister interface cls = java.lang.Class.forName('java.awt.event.ActionListener')
cls = interface java.awt.event.ActionListener
Keep in mind this is a Class object for an ActionListener, not an instance. With the ActionListener Class object we can verify that indeed this interface contains the actionPerformed method
% print out methods declared by the ActionListener interface
arrayfun(@(m)disp(char(m.toGenericString())),cls.getDeclaredMethods())
public abstract void java.awt.event.ActionListener.actionPerformed(java.awt.event.ActionEvent)
Alternatively, can ask for the system class loader directly
% get system class loader classLoader = java.lang.ClassLoader.getSystemClassLoader(); % load the Class object using a class loader cls = classLoader.loadClass('java.awt.event.ActionListener')
cls = interface java.awt.event.ActionListener
Unfortunatly, the system ClassLoader in matlab is likewise restricted to the Java static classpath.
To load Classes on the dynamic classpath we can utilize special class loaders within com.mathworks.jmi package
- com.mathworks.jmi.CustomURLClassLoader
- com.mathworks.jmi.ClassLoaderManager
and proceed as follows
% add jar file dynamically (i.e. on the dynamic classpath) javaaddpath('../ProxyBuilder.jar') % get jmi class loader classLoader = com.mathworks.jmi.ClassLoaderManager.getClassLoaderManager() % load Class for class defined in jar file cls = classLoader.loadClass('com.mypkg.TestInterface')
classLoader = com.mathworks.jmi.ClassLoaderManager@5cd9072a cls = interface com.mypkg.TestInterface
References
Java Doc: