Friday, March 23, 2007

Dynamic class behaviour in Java

In a previous post, I was using annotations to generate method pointers in Java. The functions objects were generated in a separate class file. However, if you suppose that a modern IDE would be able to generate all that code for you when you create a method, you could have the function object in the same class file as the method code itself. Since Java allows you to have a field and a method with the same name, everything works fine.
In that previous post the function object referenced the actual method in the original class file. What if we did the opposite, that is to say, the actual code is in the function object, and the method merely delegates? Here is a trivial example:

public class StringHelperDynamic {

public String toUpper(String a){
return toUpper.run(a);
}

public Function1 toUpper = new Function1 (this){
public java.lang.String run(java.lang.String a) {
return a.toUpperCase();
}
};

}

Here, we have a toUpper method that takes a String and return a String, and a toUpper function object that we can pass around, perform currying on, etc... the interesting twist of this architecture is that the toUpper field can be final or not. If not, we can then change it at runtime, and hence change the behaviour of the class at runtime, while still calling the same methods. Who needs a dynamic scripting language (-: ? To the silly example:

StringHelperDynamic me=new StringHelperDynamic();
me.toUpper=new Function1(me){
public java.lang.String run(java.lang.String a) {
return a.toLowerCase();
}
};

assertEquals("hello",me.toUpper("HELLO"));

OK, breaking the contract of the method is NOT what this is about, but you get the gist of it. The code for the Function1 class can be found here.

No comments: