Function pointers in Java

Java does not have function pointers. They are not really needed… and I have never needed them either in my 10 years of Java coding. However, I came across a rather interesting solution at work. This solution was coded in a completely different language and utilized the fact that programmers could write small bits of code, and these bits where then connected, at runtime, identified only by their name. The system makes it possible to have a model outside the actual code. And then by changing the model, the behavior of the system will change as well without needing any compilation.
“Is this even possible in Java?”, I discussed with a colleague… and we quickly agreed that it was not “the Java way” to do stuff. However, of course this needed to be tested 🙂

Of course it is possible, after all, Java ROCKS!. It’s also pretty easy as this functionality it is actually part of the Java Reflections API. Java Reflections is a rather complicated API and most tutorials about it are rather fuzzy. I decided to share my code here as a practical example of how to do it the easy way. I do not claim that this is the correct way to do it. (Probably most systems are probably better off doing stuff like this in the real Java way.)

The example will write a little fairy tale for you. The individual bits are written by different Java classes that really have nothing in common except that they all have a method named perform that takes a StringBuffer and a String as argument. The different perform methods in the classes don’t even return the same kind of values. I chose a StringBuffer and a String to have “something common for the system to work on” and “some parameter to the function”.

First we have the main class. It simply makes an array of Strings telling how the story should be built. Imagine that these data could come from some user input, read from a database or something. The main thing is, that there is no way that the compiler will be able to know which classes we will call or how we’re going to call them.

import java.util.ArrayList;
public class WriteStory {

public static void main(String[] args) {
    ArrayList functions = new ArrayList();
    functions.add("Begining");
    functions.add("BoringBit");
    functions.add("Climax");
    functions.add("Ending");
    FunctionPerformer cp = new FunctionPerformer(functions);
    cp.writeAStoryFromThisList();
    }
}

The individual bits pretty much all consist of the same Method. An example is the beginning class. I put these in a package named functions, but its just to make the code a bit prettier.

package Functions;
public class Begining {
    public int perform(StringBuffer story, String heroName){
    story.append("Once upon a time lived a hero called " + heroName + ". ");
    return 0;
    }
}

Now to the actual calling of the classes. This is done in the FunctionPerformer class. The class takes a list of strings and then calls all the strings as functions.

The important bit has been highlighted. It simply finds the class and finds the method. Then it performs the metod on the instantiated class.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class FunctionPerformer {
	private ArrayList functions;
	public FunctionPerformer(ArrayList functionList){
		this.functions = functionList;
	}

	public void writeAStoryFromThisList() {
		// Start the story.
		StringBuffer story = new StringBuffer("A little story. ");

		// Call all the individual classes.
		for (int i = 0; i < functions.size(); i++) {
			try {
				Class cls = Class.forName("Functions."+functions.get(i));

				Object instanceOfClass = cls.newInstance();
				Method methodWeWantPerformed = instanceOfClass.getClass().getMethod("perform", new Class[]{StringBuffer.class, String.class});

				//Invoke the method on the instance of our action.
				methodWeWantPerformed.invoke(instanceOfClass, story, "The Great Knight");

			} catch (ClassNotFoundException e) {
				System.out.println("Class " + functions.get(i) + " not found");
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}

		// Print the final story.
		System.out.println(story);
	}
}

The process can be made a little bit easier and more Java-like if you make all the functions inherit from a parent Function class. Then you can specify in the parent that all children have a perform method. Then the method can simply be called instead of searching for it. This way it requires a cast so I don’t really know which one is prettiest.

Class<?> cls = Class.forName("Functions."+actions.get(i));
Function instanceOfCls = (Function) cls.newInstance();
instanceOfCls.perform(story, "The great Knight");

Get the working Eclipse project here if you want to play around with it yourself.

Leave a Reply

Your email address will not be published.