@Documented @Retention(value=RUNTIME) @Target(value={FIELD,METHOD}) public @interface Delegate
The delegate type is either the type of the annotated field (or property) or the return type of the annotated method. The method can be thought of as a getter or factory method for the delegate. All public instance methods present in the delegate type and not present in the owner class will be added to owner class at compile time. The implementation of such automatically added methods is code which calls through to the delegate as per the normal delegate pattern.
As an example, consider this code:
class Event {
@Delegate
Date when
String title, url
}
def gr8conf = new Event(title: "GR8 Conference",
url: "http://www.gr8conf.org",
when: Date.parse("yyyy/MM/dd", "2009/05/18"))
def javaOne = new Event(title: "JavaOne",
url: "http://java.sun.com/javaone/",
when: Date.parse("yyyy/MM/dd", "2009/06/02"))
assert gr8conf.before(javaOne.when)
In this example, the Event
class will have a method called
before(Date otherDate)
as well as other public methods of the
Date
class.
The implementation of the before()
method will look like this:
public boolean before(Date otherDate) { return when.before(otherDate); }By default, the owner class will also be modified to implement any interfaces implemented by the delegate type. So, in the example above, because
Date
implements Cloneable
the following will be true:
assert gr8conf instanceof CloneableThis behavior can be disabled by setting the annotation's
interfaces
element to false,
i.e. @Delegate(interfaces = false)
, e.g. in the above
example, the delegate definition would become:
@Delegate
(interfaces = false) Date when
and the following would be true:
assert !(gr8conf instanceof Cloneable)If multiple delegation targets are used and the same method signature occurs in more than one of the respective delegate types, then the delegate will be made to the first defined target having that signature. If this does occur, it might be regarded as a smell (or at least poor style) and it might be clearer to do the delegation by long hand.
By default, methods of the delegate type marked as @Deprecated
are
not automatically added to the owner class (but see the technical note
about interfaces below). You can force these methods to
be added by setting the annotation's deprecated
element to true,
i.e. @Delegate(deprecated = true)
.
For example, in the example above if we change the delegate definition to:
@Delegate
(deprecated = true) Date when
then the following additional lines will execute successfully (during 2009):
assert gr8conf.year + 1900 == 2009 assert gr8conf.toGMTString().contains(" 2009 ")Otherwise these lines produce a groovy.lang.MissingPropertyException or groovy.lang.MissingMethodException respectively as those two methods are
@Deprecated
in Date
.
Technical notes:
GroovyObject
interface
are not candidates for delegation@Delegate
target@Delegate
target@Delegate
with default method arguments is known not to work in some cases.
We recommend not using these features together.deprecated
attribute will be
ignored if the owner class implements that interface (i.e. you must set interfaces=false
if you want the deprecated
attribute to be used). Otherwise, the resulting class would
not compile anyway without manually adding in any deprecated methods in the interface.@Delegate
can work in combination with @Lazy
when annotating a field (or property)Modifier and Type | Optional Element and Description |
---|---|
boolean |
allNames
Whether to apply the delegate pattern to all methods, including those with names that are considered internal.
|
boolean |
deprecated
Whether to apply the delegate pattern to deprecated methods; to avoid compilation
errors, this is ignored if the type of the delegate target is an interface and
interfaces=true . |
String[] |
excludes
List of method and/or property names to exclude when delegating.
|
Class[] |
excludeTypes
List of interfaces containing method signatures to exclude when delegating.
|
String[] |
includes
List of method and/or property names to include when delegating.
|
Class[] |
includeTypes
List of interfaces containing method signatures to include when delegating.
|
boolean |
interfaces |
boolean |
methodAnnotations
Whether to carry over annotations from the methods of the delegate
to your delegating method.
|
boolean |
parameterAnnotations
Whether to carry over annotations from the parameters of delegate
methods to your delegating method.
|
public abstract boolean interfaces
public abstract boolean deprecated
interfaces=true
.public abstract boolean methodAnnotations
public abstract boolean parameterAnnotations
public abstract String[] excludes
public abstract Class[] excludeTypes
public abstract String[] includes
public abstract Class[] includeTypes