ProgrammaticMethodReference
Ever wanted to reference a method, but didn't want to use a fragile string literal and reflection to do it? I have, but couldn't find a library to do it, so I wrote this. It requires two method calls, but that's the only way I could figure to do it, while still handling void methods.
package ca.digitalrapids.lang;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* Use like so:
* ProgrammaticMethodReference.putMethod(SomeClass.class).someMethod();
* Method method = ProgrammaticMethodReference.takeMethod();
*
* This class is thread safe.
*/
public class ProgrammaticMethodReference
{
static private ThreadLocal<Method> lastMethod = new ThreadLocal<Method>();
@SuppressWarnings("unchecked")
public static <T> T putMethod(Class<T> clazz)
{
return (T) createEnhancer(new MethodInterceptor()
{
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable
{
lastMethod.set(method);
return null;
}
}, clazz).create();
}
private static Enhancer createEnhancer(MethodInterceptor interceptor, Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(interceptor);
enhancer.setSuperclass(clazz);
return enhancer;
}
public static Method takeMethod()
{
final Method result = lastMethod.get();
if ( result == null )
throw new RuntimeException("No method set. Call putMethod first.");
return result;
}
}

0 Comments:
Post a Comment
<< Home