Does this sound a bit academically? Maybe... But there are actually situations when this is needed. One scenario I run into is related to the dynamic programming of a Groovy script. Groovy allows you to resolve a missing method inside a Groovy script against the script binding. As you probably have guessed, the missing method is expected to a Closure.
This turns out easier than I thought. After poking around the generated closure classes, it occurs to me that while closure is quite special in Groovy, it is still just a type from Java perspective. As a result, we can just code (duh :) the class. Make sure to include the constructor and doCall method.
Here is the example:
DemoBinding.java
public class DemoBinding extends Binding {
@Override
public Object getVariable(String name) {
return "foo".equals(name) ?
new FooClosure(this, this) :
super.getVariable(name);
}
class FooClosure extends Closure {
public FooClosure(Object owner, Object thisObject) {
super(owner, thisObject);
parameterTypes = new Class[1];
parameterTypes[0] = String.class;
maximumNumberOfParameters = 1;
}
public java.lang.Object doCall(String message) {
System.out.println(message);
return Closure.DONE;
}
}
}
@Override
public Object getVariable(String name) {
return "foo".equals(name) ?
new FooClosure(this, this) :
super.getVariable(name);
}
class FooClosure extends Closure {
public FooClosure(Object owner, Object thisObject) {
super(owner, thisObject);
parameterTypes = new Class[1];
parameterTypes[0] = String.class;
maximumNumberOfParameters = 1;
}
public java.lang.Object doCall(String message) {
System.out.println(message);
return Closure.DONE;
}
}
}
DemoScript.groovy
foo "Hello world"
Tester.groovy
Script script = new DemoScript()
script.setBinding (new DemoBinding())
script.run()
script.setBinding (new DemoBinding())
script.run()