Wednesday, June 27, 2007

Weird but useful generics trick

I stumbled upon the following piece of code while programmatically creating AspectJ proxies with Spring:

// create a factory that can generate a proxy for the given target object
AspectJProxyFactory factory = new AspectJProxyFactory(targetObject);

// add an aspect, the class must be an @AspectJ aspect
// you can call this as many times as you need with different aspects
factory.addAspect(SecurityManager.class);

// you can also add existing aspect instances, the type of the object supplied must be an @AspectJ aspect
factory.addAspect(usageTracker);

// now get the proxy object...
MyInterfaceType proxy = factory.getProxy();

(Pasted from here)

If you look carefully, you'll notice that A) the AspectJProxyFactory class is not parameterized, and B) the proxy creation is assigned to a MyInterfaceType without a cast. I found this to be rather confusing, and took a quick peek at the AspectJProxyFactory source:

public class AspectJProxyFactory extends ProxyCreatorSupport {

[...] // Stuff

public <T> T getProxy() {
return (T) createAopProxy().getProxy();
}

}
The return type is inferred by the assignment, regardless of the (lack of) type on the owning class, which effectively looks and feels like dynamic and static typing all at the same time!

Kind of weird, but might be useful. I, for one, was not aware of this technique.

1 comment:

Tobias Hill said...

Thanks. I just made my version of the fast-deepcopy (originally described here: http://javatechniques.com/blog/faster-deep-copies-of-java-objects/) slightly more modern:

public static <T> T copy(T orig) {
...
}