Skip to end of metadata
Go to start of metadata

Java doesn't provide any built-in delegation mechanism, and so far Groovy didn't either. But with the @Delegate transformation, a class field or property can be annotated and become an object to which method calls are delegated. In the following example, an Event class has a date delegate, and the compiler will delegate all of Date's methods invoked on the Event class to the Date delegate. As shown in the latest assert, the Event class has got a before(Date) method, and all of Date's methods.

The Groovy compiler adds all of Date's methods to the Event class, and those methods simply delegate the call to the Date field. If the delegate is not a final class, it is even possible to make the Event class a subclass of Date simply by extending Date, as shown below. No need to implement the delegation ourselves by adding each and every Date methods to our Event class, since the compiler is friendly-enough with us to do the job itself.

In the case you are delegating to an interface, however, you don't even need to explictely say you implement the interface of the delegate. The @Delegate transformation will take care of this and implement that interface. So the instances of your class will automatically be instanceof the delegate's interface.import java.util.concurrent.locks.*

In this example, our LockableList is now a composite of a list and a lock and is instanceof of List and Lock. However, if you didn't intend your class to be implementing these interfaces, you would still be able to do so by specifying a parameter on the annotation:@Delegate(interfaces = false) private List list = []

Let's have a look at another simple usage of @Delegate, for wrapping an existing class, delegating all calls to the delegate:

  • No labels