This implementation is inspired from Charles Nutters' discussion about his experiences implementing JRuby. I didn't have much time to look into it, until now. So here's my first implementation of it.
I have my Closure field a, and its body a_body.
In the Closure class, the ctor will reflectively get the declared method "a_body" by name.
When you'd like to invoke the closure, just call a.call(). Then it will normally invoke the "a_body" method with reflection.
package org.codehaus.qdg;
import org.codehaus.groovy.qdg.Closure;
public class TestGen_001 {
public Closure a = new Closure(this, "a_body");
private Object a_body(Object... args) {
System.out.println(args[0]);
System.out.println("a_body");
return null;
}
}
And here's a simple implementation of the class Closure:
package org.codehaus.groovy.qdg;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class Closure {
private Object target;
private Method method;
public Closure(Object target, String methodName) {
this.target = target;
try {
method = target.getClass().getDeclaredMethod(
methodName, new Class[]{Object[].class});
AccessController.doPrivileged(
new PrivilegedAction(){
@Override
public Object run() {
method.setAccessible(true);
return null;
}
});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public Object call(Object... args) {
try {
return method.invoke(target, (Object)args);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
A closure body, which is a private method, is accessible by setting Method#setAccessible(true).
No comments:
Post a Comment